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 
15 package com.android.systemui.statusbar.phone;
16 
17 import android.annotation.Nullable;
18 import android.content.Context;
19 import android.content.res.Configuration;
20 import android.util.AttributeSet;
21 import android.view.View;
22 import android.view.ViewGroup;
23 import android.widget.LinearLayout;
24 
25 import 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  */
31 public class ReverseLinearLayout extends LinearLayout {
32 
33     private boolean mIsLayoutRtl;
34 
ReverseLinearLayout(Context context, @Nullable AttributeSet attrs)35     public ReverseLinearLayout(Context context, @Nullable AttributeSet attrs) {
36         super(context, attrs);
37     }
38 
39     @Override
onFinishInflate()40     protected void onFinishInflate() {
41         super.onFinishInflate();
42         mIsLayoutRtl = getResources().getConfiguration()
43                 .getLayoutDirection() == LAYOUT_DIRECTION_RTL;
44     }
45 
46     @Override
addView(View child)47     public void addView(View child) {
48         reversParams(child.getLayoutParams());
49         if (mIsLayoutRtl) {
50             super.addView(child);
51         } else {
52             super.addView(child, 0);
53         }
54     }
55 
56     @Override
addView(View child, ViewGroup.LayoutParams params)57     public void addView(View child, ViewGroup.LayoutParams params) {
58         reversParams(params);
59         if (mIsLayoutRtl) {
60             super.addView(child, params);
61         } else {
62             super.addView(child, 0, params);
63         }
64     }
65 
66     @Override
onConfigurationChanged(Configuration newConfig)67     protected void onConfigurationChanged(Configuration newConfig) {
68         super.onConfigurationChanged(newConfig);
69         updateRTLOrder();
70     }
71 
72     /**
73      * In landscape, the LinearLayout is not auto mirrored since it is vertical. Therefore we
74      * have to do it manually
75      */
updateRTLOrder()76     private void updateRTLOrder() {
77         boolean isLayoutRtl = getResources().getConfiguration()
78                 .getLayoutDirection() == LAYOUT_DIRECTION_RTL;
79         if (mIsLayoutRtl != isLayoutRtl) {
80             // RTL changed, swap the order of all views.
81             int childCount = getChildCount();
82             ArrayList<View> childList = new ArrayList<>(childCount);
83             for (int i = 0; i < childCount; i++) {
84                 childList.add(getChildAt(i));
85             }
86             removeAllViews();
87             for (int i = childCount - 1; i >= 0; i--) {
88                 super.addView(childList.get(i));
89             }
90             mIsLayoutRtl = isLayoutRtl;
91         }
92     }
93 
reversParams(ViewGroup.LayoutParams params)94     private void reversParams(ViewGroup.LayoutParams params) {
95         if (params == null) {
96             return;
97         }
98         int width = params.width;
99         params.width = params.height;
100         params.height = width;
101     }
102 
103 }
104