1 package androidx.leanback.widget;
2 
3 import android.content.Context;
4 import android.content.res.TypedArray;
5 import android.util.AttributeSet;
6 import android.view.KeyEvent;
7 import android.view.View;
8 import android.view.ViewGroup;
9 import android.widget.RelativeLayout;
10 
11 import androidx.leanback.R;
12 
13 /**
14  * Relative layout implementation that assign subactions list topMargin based on a percentage
15  * given by "guidedStepKeyline" theme attribute when the topMargin is set to a negative value.
16  */
17 class GuidedActionsRelativeLayout extends RelativeLayout {
18 
19     interface InterceptKeyEventListener {
onInterceptKeyEvent(KeyEvent event)20         public boolean onInterceptKeyEvent(KeyEvent event);
21     }
22 
23     private float mKeyLinePercent;
24     private boolean mInOverride = false;
25     private InterceptKeyEventListener mInterceptKeyEventListener;
26 
GuidedActionsRelativeLayout(Context context)27     public GuidedActionsRelativeLayout(Context context) {
28         this(context, null);
29     }
30 
GuidedActionsRelativeLayout(Context context, AttributeSet attrs)31     public GuidedActionsRelativeLayout(Context context, AttributeSet attrs) {
32         this(context, attrs, 0);
33     }
34 
GuidedActionsRelativeLayout(Context context, AttributeSet attrs, int defStyle)35     public GuidedActionsRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
36         super(context, attrs, defStyle);
37         mKeyLinePercent = GuidanceStylingRelativeLayout.getKeyLinePercent(context);
38     }
39 
init()40     private void init() {
41         TypedArray ta = getContext().getTheme().obtainStyledAttributes(
42                 R.styleable.LeanbackGuidedStepTheme);
43         mKeyLinePercent = ta.getFloat(R.styleable.LeanbackGuidedStepTheme_guidedStepKeyline,
44                 40);
45         ta.recycle();
46     }
47 
48     @Override
onMeasure(int widthMeasureSpec, int heightMeasureSpec)49     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
50         final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
51         if (heightSize > 0) {
52             View view = findViewById(R.id.guidedactions_sub_list);
53             if (view != null) {
54                 ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams)
55                         view.getLayoutParams();
56                 if (lp.topMargin < 0 && !mInOverride) {
57                     mInOverride = true;
58                 }
59                 if (mInOverride) {
60                     lp.topMargin = (int) (mKeyLinePercent * heightSize / 100);
61                 }
62             }
63         }
64         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
65     }
66 
67     @Override
onLayout(boolean changed, int l, int t, int r, int b)68     protected void onLayout(boolean changed, int l, int t, int r, int b) {
69         super.onLayout(changed, l, t, r, b);
70         mInOverride = false;
71     }
72 
setInterceptKeyEventListener(InterceptKeyEventListener l)73     public void setInterceptKeyEventListener(InterceptKeyEventListener l) {
74         mInterceptKeyEventListener = l;
75     }
76 
77     @Override
dispatchKeyEvent(KeyEvent event)78     public boolean dispatchKeyEvent(KeyEvent event) {
79         if (mInterceptKeyEventListener != null) {
80             if (mInterceptKeyEventListener.onInterceptKeyEvent(event)) {
81                 return true;
82             }
83         }
84         return super.dispatchKeyEvent(event);
85     }
86 }
87