Merge "Fork navbar layout for quickstep" into pi-dev
diff --git a/packages/SystemUI/res/drawable/ic_ime_switcher_default.xml b/packages/SystemUI/res/drawable/ic_ime_switcher_default.xml
index 6a7f18b..d5f8a2a 100644
--- a/packages/SystemUI/res/drawable/ic_ime_switcher_default.xml
+++ b/packages/SystemUI/res/drawable/ic_ime_switcher_default.xml
@@ -15,11 +15,11 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24.0dp"
- android:height="24.0dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
+ android:width="20dp"
+ android:height="20dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
<path
- android:pathData="M21,4H3C1.9,4 1,4.9 1,6v13c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2V6C23,4.9 22.1,4 21,4zM21,19H3V6h18V19zM9,8h2v2H9V8zM5,8h2v2H5V8zM8,16h8v1H8V16zM13,8h2v2h-2V8zM9,12h2v2H9V12zM5,12h2v2H5V12zM13,12h2v2h-2V12zM17,8h2v2h-2V8zM17,12h2v2h-2V12z"
+ android:pathData="M19,7h2v2h-2V7zM15,7h2v2h-2V7zM3,7h2v2H3V7zM7,7h2v2H7V7zM11,7h2v2h-2V7zM19,11h2v2h-2V11zM15,11h2v2h-2V11zM3,11h2v2H3V11zM7,11h2v2H7V11zM11,11h2v2h-2V11zM7,15h10v2H7V15z"
android:fillColor="?attr/singleToneColor"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_accessibility_button.xml b/packages/SystemUI/res/drawable/ic_sysbar_accessibility_button.xml
index 6fbc404..8d569b2 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_accessibility_button.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_accessibility_button.xml
@@ -15,8 +15,8 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
+ android:width="21dp"
+ android:height="21dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_back_quick_step.xml b/packages/SystemUI/res/drawable/ic_sysbar_back_quick_step.xml
index b02a252..93b2f9c8 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_back_quick_step.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_back_quick_step.xml
@@ -19,10 +19,7 @@
android:height="28dp"
android:viewportWidth="28"
android:viewportHeight="28">
-
<path
- android:fillColor="?attr/singleToneColor"
- android:pathData="M17.25,10.15V14v3.85L14,15.95L10.69,14L14,12.05L17.25,10.15 M18.16,7.71c-0.14,0-0.28,0.04-0.42,0.12 l-4.63,2.72l-4.73,2.78c-0.52,0.3-0.52,1.05,0,1.36l4.73,2.78l4.63,2.72c0.13,0.08,0.28,0.12,0.42,0.12c0.44,0,0.84-0.36,0.84-0.86 V14V8.58C19,8.08,18.6,7.71,18.16,7.71L18.16,7.71z" />
- <path
- android:pathData="M 0 0 H 28 V 28 H 0 V 0 Z" />
+ android:pathData="M16.78,10.03l-3.97,3.97l3.97,3.97l-1.06,1.06l-5.03,-5.03l5.03,-5.03z"
+ android:fillColor="?attr/singleToneColor" />
</vector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_menu.xml b/packages/SystemUI/res/drawable/ic_sysbar_menu.xml
index 5cc1791..d53c95b 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_menu.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_menu.xml
@@ -15,8 +15,8 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="28dp"
- android:height="28dp"
+ android:width="21dp"
+ android:height="21dp"
android:viewportWidth="28"
android:viewportHeight="28">
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml
index 6c1ae99..907be01 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_rotate_button.xml
@@ -17,14 +17,14 @@
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
<vector android:name="root"
- android:width="24dp"
- android:height="24dp"
+ android:width="21dp"
+ android:height="21dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<group android:name="icon" android:pivotX="12" android:pivotY="12">
<!-- Tint color to be set directly -->
<path android:fillColor="#FFFFFFFF"
- android:pathData="M17,1.01L7,1C5.9,1 5,1.9 5,3v18c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3C19,1.9 18.1,1.01 17,1.01zM17,21H7l0,-1h10V21zM17,18H7V6h10V18zM7,4V3h10v1H7z"/>
+ android:pathData="M12,4c-0.06,0 -0.12,0.01 -0.18,0.01l1.09,-1.09L11.5,1.5L8,5l3.5,3.5l1.41,-1.41l-1.08,-1.08C11.89,6.01 11.95,6 12,6c3.31,0 6,2.69 6,6c0,1.7 -0.71,3.23 -1.85,4.32l1.41,1.41C19.06,16.28 20,14.25 20,12C20,7.59 16.41,4 12,4zM16,19l-3.5,3.5l-1.41,-1.41l1.1,-1.1C12.13,19.98 12.06,20 12,20c-4.41,0 -8,-3.59 -8,-8c0,-2.25 0.94,-4.28 2.43,-5.73l1.41,1.41C6.71,8.77 6,10.3 6,12c0,3.31 2.69,6 6,6c0.05,0 0.11,-0.01 0.16,-0.01l-1.07,-1.07l1.41,-1.41L16,19z"/>
</group>
</vector>
</aapt:attr>
diff --git a/packages/SystemUI/res/layout/contextual.xml b/packages/SystemUI/res/layout/contextual.xml
new file mode 100644
index 0000000..94591e9
--- /dev/null
+++ b/packages/SystemUI/res/layout/contextual.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/menu_container"
+ android:layout_width="@dimen/navigation_key_width"
+ android:layout_height="match_parent"
+ android:importantForAccessibility="no"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ >
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/menu"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:layout_weight="0"
+ android:scaleType="center"
+ systemui:keyCode="82"
+ systemui:playSound="false"
+ android:visibility="invisible"
+ android:contentDescription="@string/accessibility_menu"
+ android:paddingStart="@dimen/navigation_key_padding"
+ android:paddingEnd="@dimen/navigation_key_padding"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/ime_switcher"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:scaleType="center"
+ android:visibility="invisible"
+ android:contentDescription="@string/accessibility_ime_switch_button"
+ android:paddingStart="@dimen/navigation_key_padding"
+ android:paddingEnd="@dimen/navigation_key_padding"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/rotate_suggestion"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:scaleType="center"
+ android:visibility="invisible"
+ android:contentDescription="@string/accessibility_rotate_button"
+ android:paddingStart="@dimen/navigation_key_padding"
+ android:paddingEnd="@dimen/navigation_key_padding"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/accessibility_button"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:scaleType="center"
+ android:visibility="invisible"
+ android:contentDescription="@string/accessibility_accessibility_button"
+ android:paddingStart="@dimen/navigation_key_padding"
+ android:paddingEnd="@dimen/navigation_key_padding"
+ />
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml
index d72021e..baaf699 100644
--- a/packages/SystemUI/res/layout/navigation_layout.xml
+++ b/packages/SystemUI/res/layout/navigation_layout.xml
@@ -18,16 +18,14 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginStart="@dimen/rounded_corner_content_padding"
- android:layout_marginEnd="@dimen/rounded_corner_content_padding"
- android:paddingStart="@dimen/nav_content_padding"
- android:paddingEnd="@dimen/nav_content_padding">
+ android:layout_height="match_parent">
<com.android.systemui.statusbar.phone.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:paddingStart="@dimen/rounded_corner_content_padding"
+ android:paddingEnd="@dimen/rounded_corner_content_padding"
android:clipChildren="false"
android:clipToPadding="false">
@@ -36,6 +34,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
+ android:paddingStart="@dimen/nav_content_padding"
+ android:paddingEnd="@dimen/nav_content_padding"
android:clipToPadding="false"
android:clipChildren="false" />
@@ -46,6 +46,8 @@
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal"
+ android:paddingStart="@dimen/nav_content_padding"
+ android:paddingEnd="@dimen/nav_content_padding"
android:clipToPadding="false"
android:clipChildren="false" />
diff --git a/packages/SystemUI/res/layout/navigation_layout_rot90.xml b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
index 0e17e5b5..6d5b7788 100644
--- a/packages/SystemUI/res/layout/navigation_layout_rot90.xml
+++ b/packages/SystemUI/res/layout/navigation_layout_rot90.xml
@@ -18,23 +18,26 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginTop="@dimen/rounded_corner_content_padding"
- android:layout_marginBottom="@dimen/rounded_corner_content_padding"
- android:paddingTop="8dp"
- android:paddingBottom="8dp">
+ android:layout_height="match_parent">
<com.android.systemui.statusbar.phone.NearestTouchFrame
android:id="@+id/nav_buttons"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:paddingTop="@dimen/rounded_corner_content_padding"
+ android:paddingBottom="@dimen/rounded_corner_content_padding"
+ android:clipChildren="false"
+ android:clipToPadding="false">
<com.android.systemui.statusbar.phone.ReverseLinearLayout
android:id="@+id/ends_group"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:clipChildren="false" />
+ android:paddingTop="@dimen/nav_content_padding"
+ android:paddingBottom="@dimen/nav_content_padding"
+ android:clipChildren="false"
+ android:clipToPadding="false" />
<com.android.systemui.statusbar.phone.ReverseLinearLayout
android:id="@+id/center_group"
@@ -42,7 +45,10 @@
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
- android:clipChildren="false" />
+ android:paddingTop="@dimen/nav_content_padding"
+ android:paddingBottom="@dimen/nav_content_padding"
+ android:clipChildren="false"
+ android:clipToPadding="false" />
</com.android.systemui.statusbar.phone.NearestTouchFrame>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 251589b..a68ba9b 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -364,6 +364,7 @@
<!-- Nav bar button default ordering/layout -->
<string name="config_navBarLayout" translatable="false">left[.5W],back[1WC];home;recent[1WC],right[.5W]</string>
+ <string name="config_navBarLayoutQuickstep" translatable="false">back[1.7WC];home;contextual[1.7WC]</string>
<bool name="quick_settings_show_full_alarm">false</bool>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 4885c2f..e6f2c33 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -34,11 +34,12 @@
import android.widget.Space;
import com.android.systemui.Dependency;
+import com.android.systemui.OverviewProxyService;
import com.android.systemui.R;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.PluginManager;
import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider;
-import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseFrameLayout;
+import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseRelativeLayout;
import com.android.systemui.statusbar.policy.KeyButtonView;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
@@ -67,6 +68,7 @@
public static final String KEY = "key";
public static final String LEFT = "left";
public static final String RIGHT = "right";
+ public static final String CONTEXTUAL = "contextual";
public static final String GRAVITY_SEPARATOR = ";";
public static final String BUTTON_SEPARATOR = ",";
@@ -97,6 +99,9 @@
private View mLastLandscape;
private boolean mAlternativeOrder;
+ private boolean mUsingCustomLayout;
+
+ private OverviewProxyService mOverviewProxyService;
public NavigationBarInflaterView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -105,6 +110,7 @@
context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Mode displayMode = mDisplay.getMode();
isRot0Landscape = displayMode.getPhysicalWidth() > displayMode.getPhysicalHeight();
+ mOverviewProxyService = Dependency.get(OverviewProxyService.class);
}
private void createInflaters() {
@@ -136,7 +142,10 @@
}
protected String getDefaultLayout() {
- return mContext.getString(R.string.config_navBarLayout);
+ final int defaultResource = mOverviewProxyService.shouldShowSwipeUpUI()
+ ? R.string.config_navBarLayoutQuickstep
+ : R.string.config_navBarLayout;
+ return mContext.getString(defaultResource);
}
@Override
@@ -159,6 +168,7 @@
public void onTuningChanged(String key, String newValue) {
if (NAV_BAR_VIEWS.equals(key)) {
if (!Objects.equals(mCurrentLayout, newValue)) {
+ mUsingCustomLayout = newValue != null;
clearViews();
inflateLayout(newValue);
}
@@ -168,6 +178,18 @@
}
}
+ public void onLikelyDefaultLayoutChange() {
+ // Don't override custom layouts
+ if (mUsingCustomLayout) return;
+
+ // Reevaluate new layout
+ final String newValue = getDefaultLayout();
+ if (!Objects.equals(mCurrentLayout, newValue)) {
+ clearViews();
+ inflateLayout(newValue);
+ }
+ }
+
public void setButtonDispatchers(SparseArray<ButtonDispatcher> buttonDispatchers) {
mButtonDispatchers = buttonDispatchers;
for (int i = 0; i < buttonDispatchers.size(); i++) {
@@ -178,10 +200,12 @@
public void updateButtonDispatchersCurrentView() {
if (mButtonDispatchers != null) {
final int rotation = mDisplay.getRotation();
- final View view = rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180
- ? mRot0 : mRot90;
+ final boolean portrait = rotation == Surface.ROTATION_0
+ || rotation == Surface.ROTATION_180;
+ final View view = portrait ? mRot0 : mRot90;
for (int i = 0; i < mButtonDispatchers.size(); i++) {
- mButtonDispatchers.valueAt(i).setCurrentView(view);
+ final ButtonDispatcher dispatcher = mButtonDispatchers.valueAt(i);
+ dispatcher.setCurrentView(view);
}
}
}
@@ -288,8 +312,8 @@
addToDispatchers(v);
View lastView = landscape ? mLastLandscape : mLastPortrait;
View accessibilityView = v;
- if (v instanceof ReverseFrameLayout) {
- accessibilityView = ((ReverseFrameLayout) v).getChildAt(0);
+ if (v instanceof ReverseRelativeLayout) {
+ accessibilityView = ((ReverseRelativeLayout) v).getChildAt(0);
}
if (lastView != null) {
accessibilityView.setAccessibilityTraversalAfter(lastView.getId());
@@ -307,21 +331,33 @@
if (sizeStr == null) return v;
if (sizeStr.contains(WEIGHT_SUFFIX)) {
+ // To support gravity, wrap in RelativeLayout and apply gravity to it.
+ // Children wanting to use gravity must be smaller then the frame.
float weight = Float.parseFloat(sizeStr.substring(0, sizeStr.indexOf(WEIGHT_SUFFIX)));
- FrameLayout frame = new ReverseFrameLayout(mContext);
+ ReverseRelativeLayout frame = new ReverseRelativeLayout(mContext);
LayoutParams childParams = new LayoutParams(v.getLayoutParams());
- if (sizeStr.endsWith(WEIGHT_CENTERED_SUFFIX)) {
- childParams.gravity = Gravity.CENTER;
- } else {
- childParams.gravity = landscape ? (start ? Gravity.BOTTOM : Gravity.TOP)
- : (start ? Gravity.START : Gravity.END);
- }
+
+ // Compute gravity to apply
+ int gravity = (landscape) ? (start ? Gravity.TOP : Gravity.BOTTOM)
+ : (start ? Gravity.START : Gravity.END);
+ if (sizeStr.endsWith(WEIGHT_CENTERED_SUFFIX)) gravity = Gravity.CENTER;
+
+ // Set default gravity, flipped if needed in reversed layouts (270 RTL and 90 LTR)
+ frame.setDefaultGravity(gravity);
+ frame.setGravity(gravity); // Apply gravity to root
+
frame.addView(v, childParams);
+
+ // Use weighting to set the width of the frame
frame.setLayoutParams(new LinearLayout.LayoutParams(0, MATCH_PARENT, weight));
+
+ // Ensure ripples can be drawn outside bounds
frame.setClipChildren(false);
frame.setClipToPadding(false);
+
return frame;
}
+
float size = Float.parseFloat(sizeStr);
ViewGroup.LayoutParams params = v.getLayoutParams();
params.width = (int) (params.width * size);
@@ -355,6 +391,8 @@
v = inflater.inflate(R.layout.nav_key_space, parent, false);
} else if (CLIPBOARD.equals(button)) {
v = inflater.inflate(R.layout.clipboard, parent, false);
+ } else if (CONTEXTUAL.equals(button)) {
+ v = inflater.inflate(R.layout.contextual, parent, false);
} else if (button.startsWith(KEY)) {
String uri = extractImage(button);
int code = extractKeycode(button);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 49f9ee2..704e963 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -746,6 +746,12 @@
public void updateStates() {
final boolean showSwipeUpUI = mOverviewProxyService.shouldShowSwipeUpUI();
+
+ if (mNavigationInflaterView != null) {
+ // Reinflate the navbar if needed, no-op unless the swipe up state changes
+ mNavigationInflaterView.onLikelyDefaultLayoutChange();
+ }
+
updateSlippery();
reloadNavIcons();
updateNavButtonIcons();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
index bcbc345..d3ec187 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ReverseLinearLayout.java
@@ -17,10 +17,11 @@
import android.annotation.Nullable;
import android.content.Context;
import android.util.AttributeSet;
+import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.FrameLayout;
import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
import java.util.ArrayList;
@@ -48,7 +49,7 @@
@Override
public void addView(View child) {
- reverseParams(child.getLayoutParams(), child);
+ reverseParams(child.getLayoutParams(), child, mIsLayoutReverse);
if (mIsLayoutReverse) {
super.addView(child, 0);
} else {
@@ -58,7 +59,7 @@
@Override
public void addView(View child, ViewGroup.LayoutParams params) {
- reverseParams(params, child);
+ reverseParams(params, child, mIsLayoutReverse);
if (mIsLayoutReverse) {
super.addView(child, 0, params);
} else {
@@ -94,15 +95,17 @@
}
removeAllViews();
for (int i = childCount - 1; i >= 0; i--) {
- super.addView(childList.get(i));
+ final View child = childList.get(i);
+ super.addView(child);
}
mIsLayoutReverse = isLayoutReverse;
}
}
- private static void reverseParams(ViewGroup.LayoutParams params, View child) {
+ private static void reverseParams(ViewGroup.LayoutParams params, View child,
+ boolean isLayoutReverse) {
if (child instanceof Reversable) {
- ((Reversable) child).reverse();
+ ((Reversable) child).reverse(isLayoutReverse);
}
if (child.getPaddingLeft() == child.getPaddingRight()
&& child.getPaddingTop() == child.getPaddingBottom()) {
@@ -118,20 +121,48 @@
}
public interface Reversable {
- void reverse();
+ void reverse(boolean isLayoutReverse);
}
- public static class ReverseFrameLayout extends FrameLayout implements Reversable {
+ public static class ReverseRelativeLayout extends RelativeLayout implements Reversable {
- public ReverseFrameLayout(Context context) {
+ public ReverseRelativeLayout(Context context) {
super(context);
}
@Override
- public void reverse() {
- for (int i = 0; i < getChildCount(); i++) {
- View child = getChildAt(i);
- reverseParams(child.getLayoutParams(), child);
+ public void reverse(boolean isLayoutReverse) {
+ updateGravity(isLayoutReverse);
+ reverseGroup(this, isLayoutReverse);
+ }
+
+ private int mDefaultGravity = Gravity.NO_GRAVITY;
+ public void setDefaultGravity(int gravity) {
+ mDefaultGravity = gravity;
+ }
+
+ public void updateGravity(boolean isLayoutReverse) {
+ // Flip gravity if top of bottom is used
+ if (mDefaultGravity != Gravity.TOP && mDefaultGravity != Gravity.BOTTOM) return;
+
+ // Use the default (intended for 270 LTR and 90 RTL) unless layout is otherwise
+ int gravityToApply = mDefaultGravity;
+ if (isLayoutReverse) {
+ gravityToApply = mDefaultGravity == Gravity.TOP ? Gravity.BOTTOM : Gravity.TOP;
+ }
+
+ if (getGravity() != gravityToApply) setGravity(gravityToApply);
+ }
+ }
+
+ private static void reverseGroup(ViewGroup group, boolean isLayoutReverse) {
+ for (int i = 0; i < group.getChildCount(); i++) {
+ final View child = group.getChildAt(i);
+ reverseParams(child.getLayoutParams(), child, isLayoutReverse);
+
+ // Recursively reverse all children
+ if (child instanceof ViewGroup) {
+ reverseGroup((ViewGroup) child, isLayoutReverse);
}
}
}