Merge "Scroll wallet and controls under power menu." into rvc-dev
This commit is contained in:
@@ -1,71 +1,75 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/global_actions_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/global_actions_grid_root"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<com.android.systemui.globalactions.GlobalActionsFlatLayout
|
||||
android:id="@id/global_actions_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:theme="@style/qs_theme"
|
||||
android:gravity="top | center_horizontal"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:paddingBottom="@dimen/global_actions_grid_container_shadow_offset"
|
||||
android:layout_marginBottom="@dimen/global_actions_grid_container_negative_shadow_offset">
|
||||
|
||||
<com.android.systemui.globalactions.GlobalActionsFlatLayout
|
||||
android:id="@id/global_actions_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="@dimen/global_actions_top_margin"
|
||||
>
|
||||
<LinearLayout
|
||||
android:id="@android:id/list"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/global_actions_grid_side_margin"
|
||||
android:layout_marginRight="@dimen/global_actions_grid_side_margin"
|
||||
android:paddingLeft="@dimen/global_actions_grid_horizontal_padding"
|
||||
android:paddingRight="@dimen/global_actions_grid_horizontal_padding"
|
||||
android:paddingTop="@dimen/global_actions_grid_vertical_padding"
|
||||
android:paddingBottom="@dimen/global_actions_grid_vertical_padding"
|
||||
android:orientation="horizontal"
|
||||
android:theme="@style/qs_theme"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:gravity="top | center_horizontal"
|
||||
android:gravity="left"
|
||||
android:translationZ="@dimen/global_actions_translate"
|
||||
/>
|
||||
</com.android.systemui.globalactions.GlobalActionsFlatLayout>
|
||||
|
||||
<com.android.systemui.globalactions.MinHeightScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingBottom="@dimen/global_actions_grid_container_shadow_offset"
|
||||
android:layout_marginBottom="@dimen/global_actions_grid_container_negative_shadow_offset"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<LinearLayout
|
||||
android:id="@+id/global_actions_grid_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipChildren="false"
|
||||
android:orientation="vertical"
|
||||
android:clipToPadding="false"
|
||||
android:layout_marginTop="@dimen/global_actions_top_margin">
|
||||
>
|
||||
<LinearLayout
|
||||
android:id="@android:id/list"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/global_actions_grid_side_margin"
|
||||
android:layout_marginRight="@dimen/global_actions_grid_side_margin"
|
||||
android:paddingLeft="@dimen/global_actions_grid_horizontal_padding"
|
||||
android:paddingRight="@dimen/global_actions_grid_horizontal_padding"
|
||||
android:paddingTop="@dimen/global_actions_grid_vertical_padding"
|
||||
android:paddingBottom="@dimen/global_actions_grid_vertical_padding"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="left"
|
||||
android:translationZ="@dimen/global_actions_translate" />
|
||||
</com.android.systemui.globalactions.GlobalActionsFlatLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/global_actions_panel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/global_actions_view">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/global_actions_panel_container"
|
||||
android:id="@+id/global_actions_panel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
<FrameLayout
|
||||
android:id="@+id/global_actions_panel_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/global_actions_controls"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/global_actions_panel"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
||||
<LinearLayout
|
||||
android:id="@+id/global_actions_controls"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:layout_marginRight="@dimen/global_actions_grid_horizontal_padding"
|
||||
android:layout_marginLeft="@dimen/global_actions_grid_horizontal_padding"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</com.android.systemui.globalactions.MinHeightScrollView>
|
||||
</LinearLayout>
|
||||
@@ -1,38 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.android.systemui.HardwareUiLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@id/global_actions_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="top|right"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="@dimen/global_actions_top_padding"
|
||||
android:clipToPadding="false"
|
||||
android:theme="@style/qs_theme"
|
||||
android:clipChildren="false">
|
||||
|
||||
<!-- Global actions is right-aligned to be physically near power button -->
|
||||
<LinearLayout
|
||||
android:id="@android:id/list"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top|right"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/global_actions_padding"
|
||||
android:translationZ="@dimen/global_actions_translate" />
|
||||
|
||||
<!-- For separated button-->
|
||||
<FrameLayout
|
||||
android:id="@+id/separated_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top|right"
|
||||
android:layout_marginTop="6dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/global_actions_padding"
|
||||
android:translationZ="@dimen/global_actions_translate" />
|
||||
|
||||
</com.android.systemui.HardwareUiLayout>
|
||||
@@ -1,570 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.
|
||||
*/
|
||||
|
||||
package com.android.systemui;
|
||||
|
||||
import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE;
|
||||
import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE;
|
||||
import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import com.android.systemui.tuner.TunerService;
|
||||
import com.android.systemui.tuner.TunerService.Tunable;
|
||||
import com.android.systemui.util.leak.RotationUtils;
|
||||
|
||||
/**
|
||||
* Layout for placing two containers at a specific physical position on the device, relative to the
|
||||
* device's hardware, regardless of screen rotation.
|
||||
*/
|
||||
public class HardwareUiLayout extends MultiListLayout implements Tunable {
|
||||
|
||||
private static final String EDGE_BLEED = "sysui_hwui_edge_bleed";
|
||||
private static final String ROUNDED_DIVIDER = "sysui_hwui_rounded_divider";
|
||||
private final int[] mTmp2 = new int[2];
|
||||
private ViewGroup mList;
|
||||
private ViewGroup mSeparatedView;
|
||||
private int mOldHeight;
|
||||
private boolean mAnimating;
|
||||
private AnimatorSet mAnimation;
|
||||
private View mDivision;
|
||||
private HardwareBgDrawable mListBackground;
|
||||
private HardwareBgDrawable mSeparatedViewBackground;
|
||||
private Animator mAnimator;
|
||||
private boolean mCollapse;
|
||||
private int mEndPoint;
|
||||
private boolean mEdgeBleed;
|
||||
private boolean mRoundedDivider;
|
||||
private boolean mRotatedBackground;
|
||||
private boolean mSwapOrientation = true;
|
||||
|
||||
public HardwareUiLayout(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
// Manually re-initialize mRotation to portrait-mode, since this view must always
|
||||
// be constructed in portrait mode and rotated into the correct initial position.
|
||||
mRotation = ROTATION_NONE;
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ViewGroup getSeparatedView() {
|
||||
return findViewById(com.android.systemui.R.id.separated_button);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ViewGroup getListView() {
|
||||
return findViewById(android.R.id.list);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
updateSettings();
|
||||
Dependency.get(TunerService.class).addTunable(this, EDGE_BLEED, ROUNDED_DIVIDER);
|
||||
getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
getViewTreeObserver().removeOnComputeInternalInsetsListener(mInsetsListener);
|
||||
Dependency.get(TunerService.class).removeTunable(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
private void updateSettings() {
|
||||
mEdgeBleed = Settings.Secure.getInt(getContext().getContentResolver(),
|
||||
EDGE_BLEED, 0) != 0;
|
||||
mRoundedDivider = Settings.Secure.getInt(getContext().getContentResolver(),
|
||||
ROUNDED_DIVIDER, 0) != 0;
|
||||
updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
|
||||
mListBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed, getContext());
|
||||
mSeparatedViewBackground = new HardwareBgDrawable(mRoundedDivider, !mEdgeBleed,
|
||||
getContext());
|
||||
if (mList != null) {
|
||||
mList.setBackground(mListBackground);
|
||||
mSeparatedView.setBackground(mSeparatedViewBackground);
|
||||
requestLayout();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEdgeMargin(int edge) {
|
||||
if (mList != null) {
|
||||
MarginLayoutParams params = (MarginLayoutParams) mList.getLayoutParams();
|
||||
if (mRotation == ROTATION_LANDSCAPE) {
|
||||
params.topMargin = edge;
|
||||
} else if (mRotation == ROTATION_SEASCAPE) {
|
||||
params.bottomMargin = edge;
|
||||
} else {
|
||||
params.rightMargin = edge;
|
||||
}
|
||||
mList.setLayoutParams(params);
|
||||
}
|
||||
|
||||
if (mSeparatedView != null) {
|
||||
MarginLayoutParams params = (MarginLayoutParams) mSeparatedView.getLayoutParams();
|
||||
if (mRotation == ROTATION_LANDSCAPE) {
|
||||
params.topMargin = edge;
|
||||
} else if (mRotation == ROTATION_SEASCAPE) {
|
||||
params.bottomMargin = edge;
|
||||
} else {
|
||||
params.rightMargin = edge;
|
||||
}
|
||||
mSeparatedView.setLayoutParams(params);
|
||||
}
|
||||
}
|
||||
|
||||
private int getEdgePadding() {
|
||||
return getContext().getResources().getDimensionPixelSize(R.dimen.edge_margin);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
if (mList == null) {
|
||||
if (getChildCount() != 0) {
|
||||
mList = getListView();
|
||||
mList.setBackground(mListBackground);
|
||||
mSeparatedView = getSeparatedView();
|
||||
mSeparatedView.setBackground(mSeparatedViewBackground);
|
||||
updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
|
||||
mOldHeight = mList.getMeasuredHeight();
|
||||
|
||||
// Must be called to initialize view rotation correctly.
|
||||
// Requires LayoutParams, hence why this isn't called during the constructor.
|
||||
updateRotation();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int newHeight = mList.getMeasuredHeight();
|
||||
if (newHeight != mOldHeight) {
|
||||
animateChild(mOldHeight, newHeight);
|
||||
}
|
||||
|
||||
post(() -> updatePaddingAndGravityIfTooTall());
|
||||
post(() -> updatePosition());
|
||||
}
|
||||
|
||||
public void setSwapOrientation(boolean swapOrientation) {
|
||||
mSwapOrientation = swapOrientation;
|
||||
}
|
||||
|
||||
private void updateRotation() {
|
||||
int rotation = RotationUtils.getRotation(getContext());
|
||||
if (rotation != mRotation) {
|
||||
rotate(mRotation, rotation);
|
||||
mRotation = rotation;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requires LayoutParams to be set to work correctly, and therefore must be run after after
|
||||
* the HardwareUILayout has been added to the view hierarchy.
|
||||
*/
|
||||
protected void rotate(int from, int to) {
|
||||
super.rotate(from, to);
|
||||
if (from != ROTATION_NONE && to != ROTATION_NONE) {
|
||||
// Rather than handling this confusing case, just do 2 rotations.
|
||||
rotate(from, ROTATION_NONE);
|
||||
rotate(ROTATION_NONE, to);
|
||||
return;
|
||||
}
|
||||
if (from == ROTATION_LANDSCAPE || to == ROTATION_SEASCAPE) {
|
||||
rotateRight();
|
||||
} else {
|
||||
rotateLeft();
|
||||
}
|
||||
if (mAdapter.hasSeparatedItems()) {
|
||||
if (from == ROTATION_SEASCAPE || to == ROTATION_SEASCAPE) {
|
||||
// Separated view has top margin, so seascape separated view need special rotation,
|
||||
// not a full left or right rotation.
|
||||
swapLeftAndTop(mSeparatedView);
|
||||
} else if (from == ROTATION_LANDSCAPE) {
|
||||
rotateRight(mSeparatedView);
|
||||
} else {
|
||||
rotateLeft(mSeparatedView);
|
||||
}
|
||||
}
|
||||
if (to != ROTATION_NONE) {
|
||||
if (mList instanceof LinearLayout) {
|
||||
mRotatedBackground = true;
|
||||
mListBackground.setRotatedBackground(true);
|
||||
mSeparatedViewBackground.setRotatedBackground(true);
|
||||
LinearLayout linearLayout = (LinearLayout) mList;
|
||||
if (mSwapOrientation) {
|
||||
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
setOrientation(LinearLayout.HORIZONTAL);
|
||||
}
|
||||
swapDimens(mList);
|
||||
swapDimens(mSeparatedView);
|
||||
}
|
||||
} else {
|
||||
if (mList instanceof LinearLayout) {
|
||||
mRotatedBackground = false;
|
||||
mListBackground.setRotatedBackground(false);
|
||||
mSeparatedViewBackground.setRotatedBackground(false);
|
||||
LinearLayout linearLayout = (LinearLayout) mList;
|
||||
if (mSwapOrientation) {
|
||||
linearLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
setOrientation(LinearLayout.VERTICAL);
|
||||
}
|
||||
swapDimens(mList);
|
||||
swapDimens(mSeparatedView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateList() {
|
||||
super.onUpdateList();
|
||||
|
||||
for (int i = 0; i < mAdapter.getCount(); i++) {
|
||||
ViewGroup parent;
|
||||
boolean separated = mAdapter.shouldBeSeparated(i);
|
||||
if (separated) {
|
||||
parent = getSeparatedView();
|
||||
} else {
|
||||
parent = getListView();
|
||||
}
|
||||
View v = mAdapter.getView(i, null, parent);
|
||||
parent.addView(v);
|
||||
}
|
||||
}
|
||||
|
||||
private void rotateRight() {
|
||||
rotateRight(this);
|
||||
rotateRight(mList);
|
||||
swapDimens(this);
|
||||
|
||||
LayoutParams p = (LayoutParams) mList.getLayoutParams();
|
||||
p.gravity = rotateGravityRight(p.gravity);
|
||||
mList.setLayoutParams(p);
|
||||
|
||||
LayoutParams separatedViewLayoutParams = (LayoutParams) mSeparatedView.getLayoutParams();
|
||||
separatedViewLayoutParams.gravity = rotateGravityRight(separatedViewLayoutParams.gravity);
|
||||
mSeparatedView.setLayoutParams(separatedViewLayoutParams);
|
||||
|
||||
setGravity(rotateGravityRight(getGravity()));
|
||||
}
|
||||
|
||||
private void swapDimens(View v) {
|
||||
ViewGroup.LayoutParams params = v.getLayoutParams();
|
||||
int h = params.width;
|
||||
params.width = params.height;
|
||||
params.height = h;
|
||||
v.setLayoutParams(params);
|
||||
}
|
||||
|
||||
private int rotateGravityRight(int gravity) {
|
||||
int retGravity = 0;
|
||||
int layoutDirection = getLayoutDirection();
|
||||
final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
|
||||
final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
|
||||
|
||||
switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
|
||||
case Gravity.CENTER_HORIZONTAL:
|
||||
retGravity |= Gravity.CENTER_VERTICAL;
|
||||
break;
|
||||
case Gravity.RIGHT:
|
||||
retGravity |= Gravity.BOTTOM;
|
||||
break;
|
||||
case Gravity.LEFT:
|
||||
default:
|
||||
retGravity |= Gravity.TOP;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (verticalGravity) {
|
||||
case Gravity.CENTER_VERTICAL:
|
||||
retGravity |= Gravity.CENTER_HORIZONTAL;
|
||||
break;
|
||||
case Gravity.BOTTOM:
|
||||
retGravity |= Gravity.LEFT;
|
||||
break;
|
||||
case Gravity.TOP:
|
||||
default:
|
||||
retGravity |= Gravity.RIGHT;
|
||||
break;
|
||||
}
|
||||
return retGravity;
|
||||
}
|
||||
|
||||
private void rotateLeft() {
|
||||
rotateLeft(this);
|
||||
rotateLeft(mList);
|
||||
swapDimens(this);
|
||||
|
||||
LayoutParams p = (LayoutParams) mList.getLayoutParams();
|
||||
p.gravity = rotateGravityLeft(p.gravity);
|
||||
mList.setLayoutParams(p);
|
||||
|
||||
LayoutParams separatedViewLayoutParams = (LayoutParams) mSeparatedView.getLayoutParams();
|
||||
separatedViewLayoutParams.gravity = rotateGravityLeft(separatedViewLayoutParams.gravity);
|
||||
mSeparatedView.setLayoutParams(separatedViewLayoutParams);
|
||||
|
||||
setGravity(rotateGravityLeft(getGravity()));
|
||||
}
|
||||
|
||||
private int rotateGravityLeft(int gravity) {
|
||||
if (gravity == -1) {
|
||||
gravity = Gravity.TOP | Gravity.START;
|
||||
}
|
||||
int retGravity = 0;
|
||||
int layoutDirection = getLayoutDirection();
|
||||
final int absoluteGravity = Gravity.getAbsoluteGravity(gravity, layoutDirection);
|
||||
final int verticalGravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
|
||||
|
||||
switch (absoluteGravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
|
||||
case Gravity.CENTER_HORIZONTAL:
|
||||
retGravity |= Gravity.CENTER_VERTICAL;
|
||||
break;
|
||||
case Gravity.RIGHT:
|
||||
retGravity |= Gravity.TOP;
|
||||
break;
|
||||
case Gravity.LEFT:
|
||||
default:
|
||||
retGravity |= Gravity.BOTTOM;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (verticalGravity) {
|
||||
case Gravity.CENTER_VERTICAL:
|
||||
retGravity |= Gravity.CENTER_HORIZONTAL;
|
||||
break;
|
||||
case Gravity.BOTTOM:
|
||||
retGravity |= Gravity.RIGHT;
|
||||
break;
|
||||
case Gravity.TOP:
|
||||
default:
|
||||
retGravity |= Gravity.LEFT;
|
||||
break;
|
||||
}
|
||||
return retGravity;
|
||||
}
|
||||
|
||||
private void rotateLeft(View v) {
|
||||
v.setPadding(v.getPaddingTop(), v.getPaddingRight(), v.getPaddingBottom(),
|
||||
v.getPaddingLeft());
|
||||
MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
|
||||
params.setMargins(params.topMargin, params.rightMargin, params.bottomMargin,
|
||||
params.leftMargin);
|
||||
v.setLayoutParams(params);
|
||||
}
|
||||
|
||||
private void rotateRight(View v) {
|
||||
v.setPadding(v.getPaddingBottom(), v.getPaddingLeft(), v.getPaddingTop(),
|
||||
v.getPaddingRight());
|
||||
MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
|
||||
params.setMargins(params.bottomMargin, params.leftMargin, params.topMargin,
|
||||
params.rightMargin);
|
||||
v.setLayoutParams(params);
|
||||
}
|
||||
|
||||
private void swapLeftAndTop(View v) {
|
||||
v.setPadding(v.getPaddingTop(), v.getPaddingLeft(), v.getPaddingBottom(),
|
||||
v.getPaddingRight());
|
||||
MarginLayoutParams params = (MarginLayoutParams) v.getLayoutParams();
|
||||
params.setMargins(params.topMargin, params.leftMargin, params.bottomMargin,
|
||||
params.rightMargin);
|
||||
v.setLayoutParams(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||
super.onLayout(changed, left, top, right, bottom);
|
||||
|
||||
post(() -> updatePosition());
|
||||
|
||||
}
|
||||
|
||||
private void animateChild(int oldHeight, int newHeight) {
|
||||
if (true) return;
|
||||
if (mAnimating) {
|
||||
mAnimation.cancel();
|
||||
}
|
||||
mAnimating = true;
|
||||
mAnimation = new AnimatorSet();
|
||||
mAnimation.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mAnimating = false;
|
||||
}
|
||||
});
|
||||
int fromTop = mList.getTop();
|
||||
int fromBottom = mList.getBottom();
|
||||
int toTop = fromTop - ((newHeight - oldHeight) / 2);
|
||||
int toBottom = fromBottom + ((newHeight - oldHeight) / 2);
|
||||
ObjectAnimator top = ObjectAnimator.ofInt(mList, "top", fromTop, toTop);
|
||||
top.addUpdateListener(animation -> mListBackground.invalidateSelf());
|
||||
mAnimation.playTogether(top,
|
||||
ObjectAnimator.ofInt(mList, "bottom", fromBottom, toBottom));
|
||||
}
|
||||
|
||||
public void setDivisionView(View v) {
|
||||
mDivision = v;
|
||||
if (mDivision != null) {
|
||||
mDivision.addOnLayoutChangeListener(
|
||||
(v1, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
|
||||
updatePosition());
|
||||
}
|
||||
updatePosition();
|
||||
}
|
||||
|
||||
private void updatePosition() {
|
||||
if (mList == null) return;
|
||||
// If got separated button, setRotatedBackground to false,
|
||||
// all items won't get white background.
|
||||
boolean separated = mAdapter.hasSeparatedItems();
|
||||
mListBackground.setRotatedBackground(separated);
|
||||
mSeparatedViewBackground.setRotatedBackground(separated);
|
||||
if (mDivision != null && mDivision.getVisibility() == VISIBLE) {
|
||||
int index = mRotatedBackground ? 0 : 1;
|
||||
mDivision.getLocationOnScreen(mTmp2);
|
||||
float trans = mRotatedBackground ? mDivision.getTranslationX()
|
||||
: mDivision.getTranslationY();
|
||||
int viewTop = (int) (mTmp2[index] + trans);
|
||||
mList.getLocationOnScreen(mTmp2);
|
||||
viewTop -= mTmp2[index];
|
||||
setCutPoint(viewTop);
|
||||
} else {
|
||||
setCutPoint(mList.getMeasuredHeight());
|
||||
}
|
||||
}
|
||||
|
||||
private void setCutPoint(int point) {
|
||||
int curPoint = mListBackground.getCutPoint();
|
||||
if (curPoint == point) return;
|
||||
if (getAlpha() == 0 || curPoint == 0) {
|
||||
mListBackground.setCutPoint(point);
|
||||
return;
|
||||
}
|
||||
if (mAnimator != null) {
|
||||
if (mEndPoint == point) {
|
||||
return;
|
||||
}
|
||||
mAnimator.cancel();
|
||||
}
|
||||
mEndPoint = point;
|
||||
mAnimator = ObjectAnimator.ofInt(mListBackground, "cutPoint", curPoint, point);
|
||||
if (mCollapse) {
|
||||
mAnimator.setStartDelay(300);
|
||||
mCollapse = false;
|
||||
}
|
||||
mAnimator.start();
|
||||
}
|
||||
|
||||
// If current power menu height larger then screen height, remove padding to break power menu
|
||||
// alignment and set menu center vertical within the screen.
|
||||
private void updatePaddingAndGravityIfTooTall() {
|
||||
int defaultTopPadding;
|
||||
int viewsTotalHeight;
|
||||
int separatedViewTopMargin;
|
||||
int screenHeight;
|
||||
int totalHeight;
|
||||
int targetGravity;
|
||||
boolean separated = mAdapter.hasSeparatedItems();
|
||||
MarginLayoutParams params = (MarginLayoutParams) mSeparatedView.getLayoutParams();
|
||||
switch (RotationUtils.getRotation(getContext())) {
|
||||
case RotationUtils.ROTATION_LANDSCAPE:
|
||||
defaultTopPadding = getPaddingLeft();
|
||||
viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth();
|
||||
separatedViewTopMargin = separated ? params.leftMargin : 0;
|
||||
screenHeight = getMeasuredWidth();
|
||||
targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.TOP;
|
||||
break;
|
||||
case RotationUtils.ROTATION_SEASCAPE:
|
||||
defaultTopPadding = getPaddingRight();
|
||||
viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth();
|
||||
separatedViewTopMargin = separated ? params.leftMargin : 0;
|
||||
screenHeight = getMeasuredWidth();
|
||||
targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM;
|
||||
break;
|
||||
default: // Portrait
|
||||
defaultTopPadding = getPaddingTop();
|
||||
viewsTotalHeight = mList.getMeasuredHeight() + mSeparatedView.getMeasuredHeight();
|
||||
separatedViewTopMargin = separated ? params.topMargin : 0;
|
||||
screenHeight = getMeasuredHeight();
|
||||
targetGravity = Gravity.CENTER_VERTICAL|Gravity.RIGHT;
|
||||
break;
|
||||
}
|
||||
totalHeight = defaultTopPadding + viewsTotalHeight + separatedViewTopMargin;
|
||||
if (totalHeight >= screenHeight) {
|
||||
setPadding(0, 0, 0, 0);
|
||||
setGravity(targetGravity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewOutlineProvider getOutlineProvider() {
|
||||
return super.getOutlineProvider();
|
||||
}
|
||||
|
||||
public void setCollapse() {
|
||||
mCollapse = true;
|
||||
}
|
||||
|
||||
private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = inoutInfo -> {
|
||||
if (mHasOutsideTouch || (mList == null)) {
|
||||
inoutInfo.setTouchableInsets(
|
||||
ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
|
||||
return;
|
||||
}
|
||||
inoutInfo.setTouchableInsets(
|
||||
ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT);
|
||||
inoutInfo.contentInsets.set(mList.getLeft(), mList.getTop(),
|
||||
0, getBottom() - mList.getBottom());
|
||||
};
|
||||
|
||||
private float getAnimationDistance() {
|
||||
return getContext().getResources().getDimension(
|
||||
com.android.systemui.R.dimen.global_actions_panel_width) / 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAnimationOffsetX() {
|
||||
if (RotationUtils.getRotation(mContext) == ROTATION_NONE) {
|
||||
return getAnimationDistance();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAnimationOffsetY() {
|
||||
switch (RotationUtils.getRotation(getContext())) {
|
||||
case RotationUtils.ROTATION_LANDSCAPE:
|
||||
return -getAnimationDistance();
|
||||
case RotationUtils.ROTATION_SEASCAPE:
|
||||
return getAnimationDistance();
|
||||
default: // Portrait
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1574,7 +1574,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
|
||||
private ControlsUiController mControlsUiController;
|
||||
private ViewGroup mControlsView;
|
||||
private ViewGroup mContainerView;
|
||||
|
||||
ActionsDialog(Context context, MyAdapter adapter,
|
||||
GlobalActionsPanelPlugin.PanelViewController plugin, BlurUtils blurUtils,
|
||||
@@ -1671,7 +1670,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
mControlsView = findViewById(com.android.systemui.R.id.global_actions_controls);
|
||||
mGlobalActionsLayout = findViewById(com.android.systemui.R.id.global_actions_view);
|
||||
mGlobalActionsLayout.setOutsideTouchListener(view -> dismiss());
|
||||
((View) mGlobalActionsLayout.getParent()).setOnClickListener(view -> dismiss());
|
||||
mGlobalActionsLayout.setListViewAccessibilityDelegate(new View.AccessibilityDelegate() {
|
||||
@Override
|
||||
public boolean dispatchPopulateAccessibilityEvent(
|
||||
@@ -1684,6 +1682,15 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
mGlobalActionsLayout.setRotationListener(this::onRotate);
|
||||
mGlobalActionsLayout.setAdapter(mAdapter);
|
||||
|
||||
View globalActionsParent = (View) mGlobalActionsLayout.getParent();
|
||||
globalActionsParent.setOnClickListener(v -> dismiss());
|
||||
|
||||
// add fall-through dismiss handling to root view
|
||||
View rootView = findViewById(com.android.systemui.R.id.global_actions_grid_root);
|
||||
if (rootView != null) {
|
||||
rootView.setOnClickListener(v -> dismiss());
|
||||
}
|
||||
|
||||
if (shouldUsePanel()) {
|
||||
initializePanel();
|
||||
}
|
||||
@@ -1692,14 +1699,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
|
||||
mScrimAlpha = ScrimController.BUSY_SCRIM_ALPHA;
|
||||
}
|
||||
getWindow().setBackgroundDrawable(mBackgroundDrawable);
|
||||
|
||||
if (mControlsView != null) {
|
||||
mContainerView = findViewById(com.android.systemui.R.id.global_actions_container);
|
||||
mContainerView.setOnTouchListener((v, e) -> {
|
||||
dismiss();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void fixNavBarClipping() {
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.
|
||||
*/
|
||||
|
||||
package com.android.systemui.globalactions;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.ScrollView;
|
||||
|
||||
/**
|
||||
* When measured, this view sets the minimum height of its first child to be equal to its own
|
||||
* target height.
|
||||
*
|
||||
* This ensures fall-through click handlers can be placed on this view's child component.
|
||||
*/
|
||||
public class MinHeightScrollView extends ScrollView {
|
||||
public MinHeightScrollView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
View firstChild = getChildAt(0);
|
||||
if (firstChild != null) {
|
||||
firstChild.setMinimumHeight(MeasureSpec.getSize(heightMeasureSpec));
|
||||
}
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user