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 /** 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 ReverseLinearLayout(Context context, @Nullable AttributeSet attrs)39 public ReverseLinearLayout(Context context, @Nullable AttributeSet attrs) { 40 super(context, attrs); 41 } 42 43 @Override onFinishInflate()44 protected void onFinishInflate() { 45 super.onFinishInflate(); 46 updateOrder(); 47 } 48 49 @Override addView(View child)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 addView(View child, ViewGroup.LayoutParams params)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 onRtlPropertiesChanged(int layoutDirection)70 public void onRtlPropertiesChanged(int layoutDirection) { 71 super.onRtlPropertiesChanged(layoutDirection); 72 updateOrder(); 73 } 74 setAlternativeOrder(boolean alternative)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 */ updateOrder()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 reversParams(ViewGroup.LayoutParams params)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