Scroll wallet and controls under power menu.

Bug: 150694556

Test: Manual -- wallet and controls scroll beneath power menu, and clicking/swiping them works as expected. User can still dismiss the menu by tapping on any empty space and power menu controls are still functional in all three current layouts (column, grid, grid_v2) in portrait/landscape/seascape.

Change-Id: I31de9661fdcd794c845c5e0040c490bf1520cb65
This commit is contained in:
Aran Ink
2020-03-03 13:23:17 -05:00
parent 8ebe5c222d
commit 0609026659
5 changed files with 113 additions and 675 deletions

View File

@@ -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>

View File

@@ -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>

View File

@@ -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;
}
}
}

View File

@@ -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() {

View File

@@ -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);
}
}