Home | History | Annotate | Download | only in widget
      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.content.Context;
     17 import android.graphics.Rect;
     18 import android.util.AttributeSet;
     19 import android.view.View;
     20 import android.view.ViewGroup;
     21 import android.widget.LinearLayout;
     22 
     23 import java.util.ArrayList;
     24 
     25 class ControlBar extends LinearLayout {
     26 
     27     public interface OnChildFocusedListener {
     28         public void onChildFocusedListener(View child, View focused);
     29     }
     30 
     31     private int mChildMarginFromCenter;
     32     private OnChildFocusedListener mOnChildFocusedListener;
     33     int mLastFocusIndex = -1;
     34     boolean mDefaultFocusToMiddle = true;
     35 
     36     public ControlBar(Context context, AttributeSet attrs) {
     37         super(context, attrs);
     38     }
     39 
     40     public ControlBar(Context context, AttributeSet attrs, int defStyle) {
     41         super(context, attrs, defStyle);
     42     }
     43 
     44     void setDefaultFocusToMiddle(boolean defaultFocusToMiddle) {
     45         mDefaultFocusToMiddle = defaultFocusToMiddle;
     46     }
     47 
     48     int getDefaultFocusIndex() {
     49         return mDefaultFocusToMiddle ? getChildCount() / 2 : 0;
     50     }
     51 
     52     @Override
     53     protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
     54         if (getChildCount() > 0) {
     55             int index = mLastFocusIndex >= 0 && mLastFocusIndex < getChildCount()
     56                     ? mLastFocusIndex : getDefaultFocusIndex();
     57             if (getChildAt(index).requestFocus(direction, previouslyFocusedRect)) {
     58                 return true;
     59             }
     60         }
     61         return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
     62     }
     63 
     64     @Override
     65     public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
     66         if ((direction == ViewGroup.FOCUS_UP || direction == ViewGroup.FOCUS_DOWN)) {
     67             if (mLastFocusIndex >= 0 && mLastFocusIndex < getChildCount()) {
     68                 views.add(getChildAt(mLastFocusIndex));
     69             } else if (getChildCount() > 0) {
     70                 views.add(getChildAt(getDefaultFocusIndex()));
     71             }
     72         } else {
     73             super.addFocusables(views, direction, focusableMode);
     74         }
     75     }
     76 
     77     public void setOnChildFocusedListener(OnChildFocusedListener listener) {
     78         mOnChildFocusedListener = listener;
     79     }
     80 
     81     public void setChildMarginFromCenter(int marginFromCenter) {
     82         mChildMarginFromCenter = marginFromCenter;
     83     }
     84 
     85     @Override
     86     public void requestChildFocus (View child, View focused) {
     87         super.requestChildFocus(child, focused);
     88         mLastFocusIndex = indexOfChild(child);
     89         if (mOnChildFocusedListener != null) {
     90             mOnChildFocusedListener.onChildFocusedListener(child, focused);
     91         }
     92     }
     93 
     94     @Override
     95     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     96         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     97         if (mChildMarginFromCenter <= 0) {
     98             return;
     99         }
    100 
    101         int totalExtraMargin = 0;
    102         for (int i = 0; i < getChildCount() - 1; i++) {
    103             View first = getChildAt(i);
    104             View second = getChildAt(i+1);
    105             int measuredWidth = first.getMeasuredWidth() + second.getMeasuredWidth();
    106             int marginStart = mChildMarginFromCenter - measuredWidth / 2;
    107             LayoutParams lp = (LayoutParams) second.getLayoutParams();
    108             int extraMargin = marginStart - lp.getMarginStart();
    109             lp.setMarginStart(marginStart);
    110             second.setLayoutParams(lp);
    111             totalExtraMargin += extraMargin;
    112         }
    113         setMeasuredDimension(getMeasuredWidth() + totalExtraMargin, getMeasuredHeight());
    114     }
    115 }
    116