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}