13659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu/* 23659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu * Copyright (C) 2014 The Android Open Source Project 33659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu * 43659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 53659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu * in compliance with the License. You may obtain a copy of the License at 63659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu * 73659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu * http://www.apache.org/licenses/LICENSE-2.0 83659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu * 93659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu * Unless required by applicable law or agreed to in writing, software distributed under the License 103659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 113659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu * or implied. See the License for the specific language governing permissions and limitations under 123659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu * the License. 133659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu */ 14ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.leanback.widget; 153659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu 16ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 1726d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu 183659dc62f9e55b1043edb4105c311c8ef997f2aeDake Guimport android.content.Context; 193659dc62f9e55b1043edb4105c311c8ef997f2aeDake Guimport android.util.AttributeSet; 2026d09ce0e088ef4c69538ead9e7ee79905a047feDake Guimport android.view.View; 213659dc62f9e55b1043edb4105c311c8ef997f2aeDake Guimport android.widget.LinearLayout; 223659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu 238619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikasimport androidx.annotation.RestrictTo; 248619e0ef7062b6a714f22af993e4b440fae7ef08Aurimas Liutikas 2526d09ce0e088ef4c69538ead9e7ee79905a047feDake Guimport java.util.ArrayList; 2626d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu 2726d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu/** 2826d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu * @hide 2926d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu */ 3026d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu@RestrictTo(LIBRARY_GROUP) 3126d09ce0e088ef4c69538ead9e7ee79905a047feDake Gupublic class NonOverlappingLinearLayout extends LinearLayout { 3226d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu 3326d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu boolean mFocusableViewAvailableFixEnabled = false; 3426d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu boolean mDeferFocusableViewAvailableInLayout; 3526d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu final ArrayList<ArrayList<View>> mSortedAvailableViews = new ArrayList(); 3626d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu 373659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu 38ceb7ab2ddd6e157cd4ade0f14a382c39428163c4Dake Gu public NonOverlappingLinearLayout(Context context) { 393659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu this(context, null); 403659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu } 413659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu 42ceb7ab2ddd6e157cd4ade0f14a382c39428163c4Dake Gu public NonOverlappingLinearLayout(Context context, AttributeSet attrs) { 433659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu this(context, attrs, 0); 443659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu } 453659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu 46ceb7ab2ddd6e157cd4ade0f14a382c39428163c4Dake Gu public NonOverlappingLinearLayout(Context context, AttributeSet attrs, int defStyle) { 473659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu super(context, attrs, defStyle); 483659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu } 493659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu 503659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu /** 51a00bada00bff4a58436a39472ab14ccb7a8f619dCraig Stout * Avoids creating a hardware layer when animating alpha. 523659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu */ 533659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu @Override 543659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu public boolean hasOverlappingRendering() { 553659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu return false; 563659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu } 5726d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu 5826d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu public void setFocusableViewAvailableFixEnabled(boolean enabled) { 5926d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu mFocusableViewAvailableFixEnabled = enabled; 6026d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 6126d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu 6226d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu @Override 6326d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu protected void onLayout(boolean changed, int l, int t, int r, int b) { 6426d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu try { 6526d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu mDeferFocusableViewAvailableInLayout = mFocusableViewAvailableFixEnabled 6626d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu && getOrientation() == HORIZONTAL 6726d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu && getLayoutDirection() == LAYOUT_DIRECTION_RTL; 6826d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu if (mDeferFocusableViewAvailableInLayout) { 6926d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu while (mSortedAvailableViews.size() > getChildCount()) { 7026d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu mSortedAvailableViews.remove(mSortedAvailableViews.size() - 1); 7126d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 7226d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu while (mSortedAvailableViews.size() < getChildCount()) { 7326d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu mSortedAvailableViews.add(new ArrayList()); 7426d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 7526d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 7626d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu super.onLayout(changed, l, t, r, b); 7726d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu if (mDeferFocusableViewAvailableInLayout) { 7826d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu for (int i = 0; i < mSortedAvailableViews.size(); i++) { 7926d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu for (int j = 0; j < mSortedAvailableViews.get(i).size(); j++) { 8026d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu super.focusableViewAvailable(mSortedAvailableViews.get(i).get(j)); 8126d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 8226d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 8326d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 8426d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } finally { 8526d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu if (mDeferFocusableViewAvailableInLayout) { 8626d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu mDeferFocusableViewAvailableInLayout = false; 8726d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu for (int i = 0; i < mSortedAvailableViews.size(); i++) { 8826d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu mSortedAvailableViews.get(i).clear(); 8926d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 9026d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 9126d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 9226d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 9326d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu 9426d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu @Override 9526d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu public void focusableViewAvailable(View v) { 9626d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu if (mDeferFocusableViewAvailableInLayout) { 9726d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu View i = v; 9826d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu int index = -1; 9926d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu while (i != this && i != null) { 10026d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu if (i.getParent() == this) { 10126d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu index = indexOfChild(i); 10226d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu break; 10326d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 10426d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu i = (View) i.getParent(); 10526d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 10626d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu if (index != -1) { 10726d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu mSortedAvailableViews.get(index).add(v); 10826d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 10926d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } else { 11026d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu super.focusableViewAvailable(v); 11126d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 11226d09ce0e088ef4c69538ead9e7ee79905a047feDake Gu } 1133659dc62f9e55b1043edb4105c311c8ef997f2aeDake Gu}