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 static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP;
     17 
     18 import android.content.Context;
     19 import android.util.AttributeSet;
     20 import android.view.View;
     21 import android.widget.LinearLayout;
     22 
     23 import androidx.annotation.RestrictTo;
     24 
     25 import java.util.ArrayList;
     26 
     27 /**
     28  * @hide
     29  */
     30 @RestrictTo(LIBRARY_GROUP)
     31 public class NonOverlappingLinearLayout extends LinearLayout {
     32 
     33     boolean mFocusableViewAvailableFixEnabled = false;
     34     boolean mDeferFocusableViewAvailableInLayout;
     35     final ArrayList<ArrayList<View>> mSortedAvailableViews = new ArrayList();
     36 
     37 
     38     public NonOverlappingLinearLayout(Context context) {
     39         this(context, null);
     40     }
     41 
     42     public NonOverlappingLinearLayout(Context context, AttributeSet attrs) {
     43         this(context, attrs, 0);
     44     }
     45 
     46     public NonOverlappingLinearLayout(Context context, AttributeSet attrs, int defStyle) {
     47         super(context, attrs, defStyle);
     48     }
     49 
     50     /**
     51      * Avoids creating a hardware layer when animating alpha.
     52      */
     53     @Override
     54     public boolean hasOverlappingRendering() {
     55         return false;
     56     }
     57 
     58     public void setFocusableViewAvailableFixEnabled(boolean enabled) {
     59         mFocusableViewAvailableFixEnabled = enabled;
     60     }
     61 
     62     @Override
     63     protected void onLayout(boolean changed, int l, int t, int r, int b) {
     64         try {
     65             mDeferFocusableViewAvailableInLayout = mFocusableViewAvailableFixEnabled
     66                     && getOrientation() == HORIZONTAL
     67                     && getLayoutDirection() == LAYOUT_DIRECTION_RTL;
     68             if (mDeferFocusableViewAvailableInLayout) {
     69                 while (mSortedAvailableViews.size() > getChildCount()) {
     70                     mSortedAvailableViews.remove(mSortedAvailableViews.size() - 1);
     71                 }
     72                 while (mSortedAvailableViews.size() < getChildCount()) {
     73                     mSortedAvailableViews.add(new ArrayList());
     74                 }
     75             }
     76             super.onLayout(changed, l, t, r, b);
     77             if (mDeferFocusableViewAvailableInLayout) {
     78                 for (int i = 0; i < mSortedAvailableViews.size(); i++) {
     79                     for (int j = 0; j < mSortedAvailableViews.get(i).size(); j++) {
     80                         super.focusableViewAvailable(mSortedAvailableViews.get(i).get(j));
     81                     }
     82                 }
     83             }
     84         } finally {
     85             if (mDeferFocusableViewAvailableInLayout) {
     86                 mDeferFocusableViewAvailableInLayout = false;
     87                 for (int i = 0; i < mSortedAvailableViews.size(); i++) {
     88                     mSortedAvailableViews.get(i).clear();
     89                 }
     90             }
     91         }
     92     }
     93 
     94     @Override
     95     public void focusableViewAvailable(View v) {
     96         if (mDeferFocusableViewAvailableInLayout) {
     97             View i = v;
     98             int index = -1;
     99             while (i != this && i != null) {
    100                 if (i.getParent() == this) {
    101                     index = indexOfChild(i);
    102                     break;
    103                 }
    104                 i = (View) i.getParent();
    105             }
    106             if (index != -1) {
    107                 mSortedAvailableViews.get(index).add(v);
    108             }
    109         } else {
    110             super.focusableViewAvailable(v);
    111         }
    112     }
    113 }