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