1/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except 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
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11 * KIND, either express or implied. See the License for the specific language governing
12 * permissions and limitations under the License.
13 */
14
15package com.android.systemui.statusbar.phone;
16
17import android.annotation.Nullable;
18import android.content.Context;
19import android.content.res.Configuration;
20import android.util.AttributeSet;
21import android.view.View;
22import android.view.ViewGroup;
23import android.widget.LinearLayout;
24
25import java.util.ArrayList;
26
27/**
28 * Automatically reverses the order of children as they are added.
29 * Also reverse the width and height values of layout params
30 */
31public class ReverseLinearLayout extends LinearLayout {
32
33    /** If true, the layout is reversed vs. a regular linear layout */
34    private boolean mIsLayoutReverse;
35
36    /** If true, the layout is opposite to it's natural reversity from the layout direction */
37    private boolean mIsAlternativeOrder;
38
39    public ReverseLinearLayout(Context context, @Nullable AttributeSet attrs) {
40        super(context, attrs);
41    }
42
43    @Override
44    protected void onFinishInflate() {
45        super.onFinishInflate();
46        updateOrder();
47    }
48
49    @Override
50    public void addView(View child) {
51        reversParams(child.getLayoutParams());
52        if (mIsLayoutReverse) {
53            super.addView(child, 0);
54        } else {
55            super.addView(child);
56        }
57    }
58
59    @Override
60    public void addView(View child, ViewGroup.LayoutParams params) {
61        reversParams(params);
62        if (mIsLayoutReverse) {
63            super.addView(child, 0, params);
64        } else {
65            super.addView(child, params);
66        }
67    }
68
69    @Override
70    public void onRtlPropertiesChanged(int layoutDirection) {
71        super.onRtlPropertiesChanged(layoutDirection);
72        updateOrder();
73    }
74
75    public void setAlternativeOrder(boolean alternative) {
76        mIsAlternativeOrder = alternative;
77        updateOrder();
78    }
79
80    /**
81     * In landscape, the LinearLayout is not auto mirrored since it is vertical. Therefore we
82     * have to do it manually
83     */
84    private void updateOrder() {
85        boolean isLayoutRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
86        boolean isLayoutReverse = isLayoutRtl ^ mIsAlternativeOrder;
87
88        if (mIsLayoutReverse != isLayoutReverse) {
89            // reversity changed, swap the order of all views.
90            int childCount = getChildCount();
91            ArrayList<View> childList = new ArrayList<>(childCount);
92            for (int i = 0; i < childCount; i++) {
93                childList.add(getChildAt(i));
94            }
95            removeAllViews();
96            for (int i = childCount - 1; i >= 0; i--) {
97                super.addView(childList.get(i));
98            }
99            mIsLayoutReverse = isLayoutReverse;
100        }
101    }
102
103    private void reversParams(ViewGroup.LayoutParams params) {
104        if (params == null) {
105            return;
106        }
107        int width = params.width;
108        params.width = params.height;
109        params.height = width;
110    }
111
112}
113