1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 package androidx.leanback.widget;
15 
16 import android.graphics.Rect;
17 import android.view.View;
18 import android.view.View.MeasureSpec;
19 import android.view.ViewGroup;
20 import android.view.ViewGroup.MarginLayoutParams;
21 
22 import androidx.core.view.ViewCompat;
23 
24 /**
25  * A helper class for showing a hover card view below a {@link HorizontalGridView}.  The hover card
26  * is aligned to the starting edge of the selected child view.  If there is no space when scrolling
27  * to the end, the ending edge of the hover card will be aligned to the ending edge of the parent
28  * view, excluding padding.
29  */
30 public final class HorizontalHoverCardSwitcher extends PresenterSwitcher {
31     // left and right of selected card view
32     int mCardLeft, mCardRight;
33 
34     private int[] mTmpOffsets = new int[2];
35     private Rect mTmpRect = new Rect();
36 
37     @Override
insertView(View view)38     protected void insertView(View view) {
39         // append hovercard to the end of container
40         getParentViewGroup().addView(view);
41     }
42 
43     @Override
onViewSelected(View view)44     protected void onViewSelected(View view) {
45         int rightLimit = getParentViewGroup().getWidth() - getParentViewGroup().getPaddingRight();
46         int leftLimit = getParentViewGroup().getPaddingLeft();
47         // measure the hover card width; if it's too large, align hover card
48         // end edge with row view's end edge, otherwise align start edges.
49         view.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
50         MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
51         boolean isRtl = ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_RTL;
52         if (!isRtl && mCardLeft + view.getMeasuredWidth() > rightLimit) {
53             params.leftMargin = rightLimit  - view.getMeasuredWidth();
54         } else if (isRtl && mCardLeft < leftLimit) {
55             params.leftMargin = leftLimit;
56         } else if (isRtl) {
57             params.leftMargin = mCardRight - view.getMeasuredWidth();
58         } else {
59             params.leftMargin = mCardLeft;
60         }
61         view.requestLayout();
62     }
63 
64     /**
65      * Select a childView inside a grid view and create/bind a corresponding hover card view
66      * for the object.
67      */
select(HorizontalGridView gridView, View childView, Object object)68     public void select(HorizontalGridView gridView, View childView, Object object) {
69         ViewGroup parent = getParentViewGroup();
70         gridView.getViewSelectedOffsets(childView, mTmpOffsets);
71         mTmpRect.set(0, 0, childView.getWidth(), childView.getHeight());
72         parent.offsetDescendantRectToMyCoords(childView, mTmpRect);
73         mCardLeft = mTmpRect.left - mTmpOffsets[0];
74         mCardRight = mTmpRect.right - mTmpOffsets[0];
75         select(object);
76     }
77 
78 }
79