Merge changes I60f2bedb,Ie0e3647b,I1c77a810 into sc-v2-dev am: 831ffad143
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15465258 Change-Id: Ide7b4f9d954c7db26fa4d4986c9020fba3707fd0
This commit is contained in:
@@ -17,7 +17,7 @@
|
|||||||
<com.android.wm.shell.common.AlphaOptimizedButton
|
<com.android.wm.shell.common.AlphaOptimizedButton
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
style="@android:style/Widget.DeviceDefault.Button.Borderless"
|
style="@android:style/Widget.DeviceDefault.Button.Borderless"
|
||||||
android:id="@+id/settings_button"
|
android:id="@+id/manage_button"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="@dimen/bubble_manage_button_height"
|
android:layout_height="@dimen/bubble_manage_button_height"
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:paddingTop="48dp"
|
android:paddingTop="48dp"
|
||||||
android:paddingBottom="48dp"
|
android:paddingBottom="48dp"
|
||||||
android:paddingStart="@dimen/bubble_stack_user_education_side_inset"
|
|
||||||
android:paddingEnd="16dp"
|
android:paddingEnd="16dp"
|
||||||
android:layout_marginEnd="24dp"
|
android:layout_marginEnd="24dp"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:paddingTop="28dp"
|
android:paddingTop="28dp"
|
||||||
android:paddingBottom="16dp"
|
android:paddingBottom="16dp"
|
||||||
android:paddingStart="@dimen/bubble_expanded_view_padding"
|
|
||||||
android:paddingEnd="48dp"
|
android:paddingEnd="48dp"
|
||||||
android:layout_marginEnd="24dp"
|
android:layout_marginEnd="24dp"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
@@ -66,27 +65,21 @@
|
|||||||
android:id="@+id/button_layout"
|
android:id="@+id/button_layout"
|
||||||
android:orientation="horizontal" >
|
android:orientation="horizontal" >
|
||||||
|
|
||||||
<com.android.wm.shell.common.AlphaOptimizedButton
|
<include
|
||||||
style="@android:style/Widget.Material.Button.Borderless"
|
layout="@layout/bubble_manage_button"
|
||||||
android:id="@+id/manage"
|
|
||||||
android:layout_gravity="start"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:focusable="true"
|
|
||||||
android:clickable="false"
|
|
||||||
android:text="@string/manage_bubbles_text"
|
|
||||||
android:textColor="@android:color/system_neutral1_900"
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<com.android.wm.shell.common.AlphaOptimizedButton
|
<com.android.wm.shell.common.AlphaOptimizedButton
|
||||||
style="@android:style/Widget.Material.Button.Borderless"
|
style="@android:style/Widget.DeviceDefault.Button.Borderless"
|
||||||
android:id="@+id/got_it"
|
android:id="@+id/got_it"
|
||||||
android:layout_gravity="start"
|
android:layout_gravity="start"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="@dimen/bubble_manage_button_height"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:text="@string/bubbles_user_education_got_it"
|
android:text="@string/bubbles_user_education_got_it"
|
||||||
|
android:textSize="@*android:dimen/text_size_body_2_material"
|
||||||
android:textColor="@android:color/system_neutral1_900"
|
android:textColor="@android:color/system_neutral1_900"
|
||||||
|
android:background="@drawable/bubble_manage_btn_bg"
|
||||||
/>
|
/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -184,14 +184,8 @@
|
|||||||
<dimen name="bubble_dismiss_target_padding_x">40dp</dimen>
|
<dimen name="bubble_dismiss_target_padding_x">40dp</dimen>
|
||||||
<dimen name="bubble_dismiss_target_padding_y">20dp</dimen>
|
<dimen name="bubble_dismiss_target_padding_y">20dp</dimen>
|
||||||
<dimen name="bubble_manage_menu_elevation">4dp</dimen>
|
<dimen name="bubble_manage_menu_elevation">4dp</dimen>
|
||||||
|
<!-- Size of user education views on large screens (phone is just match parent). -->
|
||||||
<!-- Bubbles user education views -->
|
<dimen name="bubbles_user_education_width_large_screen">400dp</dimen>
|
||||||
<dimen name="bubbles_manage_education_width">160dp</dimen>
|
|
||||||
<!-- The inset from the top bound of the manage button to place the user education. -->
|
|
||||||
<dimen name="bubbles_manage_education_top_inset">65dp</dimen>
|
|
||||||
<!-- Size of padding for the user education cling, this should at minimum be larger than
|
|
||||||
individual_bubble_size + some padding. -->
|
|
||||||
<dimen name="bubble_stack_user_education_side_inset">72dp</dimen>
|
|
||||||
|
|
||||||
<!-- The width/height of the size compat restart button. -->
|
<!-- The width/height of the size compat restart button. -->
|
||||||
<dimen name="size_compat_button_size">48dp</dimen>
|
<dimen name="size_compat_button_size">48dp</dimen>
|
||||||
|
|||||||
@@ -636,10 +636,16 @@ public class BubbleController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** For the overflow to be focusable & receive key events the flags must be update. **/
|
/**
|
||||||
void updateWindowFlagsForOverflow(boolean showingOverflow) {
|
* In some situations bubble's should be able to receive key events for back:
|
||||||
|
* - when the bubble overflow is showing
|
||||||
|
* - when the user education for the stack is showing.
|
||||||
|
*
|
||||||
|
* @param interceptBack whether back should be intercepted or not.
|
||||||
|
*/
|
||||||
|
void updateWindowFlagsForBackpress(boolean interceptBack) {
|
||||||
if (mStackView != null && mAddedToWindowManager) {
|
if (mStackView != null && mAddedToWindowManager) {
|
||||||
mWmLayoutParams.flags = showingOverflow
|
mWmLayoutParams.flags = interceptBack
|
||||||
? 0
|
? 0
|
||||||
: WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
: WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ public class BubbleExpandedView extends LinearLayout {
|
|||||||
@Override
|
@Override
|
||||||
public void onBackPressedOnTaskRoot(int taskId) {
|
public void onBackPressedOnTaskRoot(int taskId) {
|
||||||
if (mTaskId == taskId && mStackView.isExpanded()) {
|
if (mTaskId == taskId && mStackView.isExpanded()) {
|
||||||
mController.collapseStack();
|
mStackView.onBackPressed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ public class BubbleOverflowContainerView extends LinearLayout {
|
|||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
if (mController != null) {
|
if (mController != null) {
|
||||||
// For the overflow to get key events (e.g. back press) we need to adjust the flags
|
// For the overflow to get key events (e.g. back press) we need to adjust the flags
|
||||||
mController.updateWindowFlagsForOverflow(true);
|
mController.updateWindowFlagsForBackpress(true);
|
||||||
}
|
}
|
||||||
setOnKeyListener(mKeyListener);
|
setOnKeyListener(mKeyListener);
|
||||||
}
|
}
|
||||||
@@ -151,7 +151,7 @@ public class BubbleOverflowContainerView extends LinearLayout {
|
|||||||
protected void onDetachedFromWindow() {
|
protected void onDetachedFromWindow() {
|
||||||
super.onDetachedFromWindow();
|
super.onDetachedFromWindow();
|
||||||
if (mController != null) {
|
if (mController != null) {
|
||||||
mController.updateWindowFlagsForOverflow(false);
|
mController.updateWindowFlagsForBackpress(false);
|
||||||
}
|
}
|
||||||
setOnKeyListener(null);
|
setOnKeyListener(null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -241,6 +241,13 @@ public class BubblePositioner {
|
|||||||
return mPositionRect;
|
return mPositionRect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a rect of the screen size.
|
||||||
|
*/
|
||||||
|
public Rect getScreenRect() {
|
||||||
|
return mScreenRect;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the relevant insets (status bar, nav bar, cutouts). If taskbar is showing, its
|
* @return the relevant insets (status bar, nav bar, cutouts). If taskbar is showing, its
|
||||||
* inset is not included here.
|
* inset is not included here.
|
||||||
|
|||||||
@@ -110,9 +110,6 @@ public class BubbleStackView extends FrameLayout
|
|||||||
|
|
||||||
private static final int FADE_IN_DURATION = 320;
|
private static final int FADE_IN_DURATION = 320;
|
||||||
|
|
||||||
/** Percent to darken the bubbles when they're in the dismiss target. */
|
|
||||||
private static final float DARKEN_PERCENT = 0.3f;
|
|
||||||
|
|
||||||
/** How long to wait, in milliseconds, before hiding the flyout. */
|
/** How long to wait, in milliseconds, before hiding the flyout. */
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final int FLYOUT_HIDE_AFTER = 5000;
|
static final int FLYOUT_HIDE_AFTER = 5000;
|
||||||
@@ -559,7 +556,7 @@ public class BubbleStackView extends FrameLayout
|
|||||||
|
|
||||||
if (mBubbleData.isExpanded()) {
|
if (mBubbleData.isExpanded()) {
|
||||||
if (mManageEduView != null) {
|
if (mManageEduView != null) {
|
||||||
mManageEduView.hide(false /* show */);
|
mManageEduView.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're expanded, tell the animation controller to prepare to drag this bubble,
|
// If we're expanded, tell the animation controller to prepare to drag this bubble,
|
||||||
@@ -797,8 +794,6 @@ public class BubbleStackView extends FrameLayout
|
|||||||
mBubbleContainer.setClipChildren(false);
|
mBubbleContainer.setClipChildren(false);
|
||||||
addView(mBubbleContainer, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
|
addView(mBubbleContainer, new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
|
||||||
|
|
||||||
updateUserEdu();
|
|
||||||
|
|
||||||
mExpandedViewContainer = new FrameLayout(context);
|
mExpandedViewContainer = new FrameLayout(context);
|
||||||
mExpandedViewContainer.setElevation(elevation);
|
mExpandedViewContainer.setElevation(elevation);
|
||||||
mExpandedViewContainer.setClipChildren(false);
|
mExpandedViewContainer.setClipChildren(false);
|
||||||
@@ -932,8 +927,10 @@ public class BubbleStackView extends FrameLayout
|
|||||||
setOnClickListener(view -> {
|
setOnClickListener(view -> {
|
||||||
if (mShowingManage) {
|
if (mShowingManage) {
|
||||||
showManageMenu(false /* show */);
|
showManageMenu(false /* show */);
|
||||||
|
} else if (mManageEduView != null && mManageEduView.getVisibility() == VISIBLE) {
|
||||||
|
mManageEduView.hide();
|
||||||
} else if (mStackEduView != null && mStackEduView.getVisibility() == VISIBLE) {
|
} else if (mStackEduView != null && mStackEduView.getVisibility() == VISIBLE) {
|
||||||
mStackEduView.hide(false);
|
mStackEduView.hide(false /* isExpanding */);
|
||||||
} else if (mBubbleData.isExpanded()) {
|
} else if (mBubbleData.isExpanded()) {
|
||||||
mBubbleData.setExpanded(false);
|
mBubbleData.setExpanded(false);
|
||||||
}
|
}
|
||||||
@@ -1132,10 +1129,10 @@ public class BubbleStackView extends FrameLayout
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mManageEduView == null) {
|
if (mManageEduView == null) {
|
||||||
mManageEduView = new ManageEducationView(mContext);
|
mManageEduView = new ManageEducationView(mContext, mPositioner);
|
||||||
addView(mManageEduView);
|
addView(mManageEduView);
|
||||||
}
|
}
|
||||||
mManageEduView.show(mExpandedBubble.getExpandedView(), mTempRect);
|
mManageEduView.show(mExpandedBubble.getExpandedView());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1163,21 +1160,27 @@ public class BubbleStackView extends FrameLayout
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (mStackEduView == null) {
|
if (mStackEduView == null) {
|
||||||
mStackEduView = new StackEducationView(mContext);
|
mStackEduView = new StackEducationView(mContext, mPositioner, mBubbleController);
|
||||||
addView(mStackEduView);
|
addView(mStackEduView);
|
||||||
}
|
}
|
||||||
mBubbleContainer.bringToFront();
|
mBubbleContainer.bringToFront();
|
||||||
return mStackEduView.show(mPositioner.getDefaultStartPosition());
|
return mStackEduView.show(mPositioner.getDefaultStartPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recreates & shows the education views. Call when a theme/config change happens.
|
||||||
private void updateUserEdu() {
|
private void updateUserEdu() {
|
||||||
maybeShowStackEdu();
|
if (mStackEduView != null && mStackEduView.getVisibility() == VISIBLE) {
|
||||||
if (mManageEduView != null) {
|
removeView(mStackEduView);
|
||||||
mManageEduView.invalidate();
|
mStackEduView = new StackEducationView(mContext, mPositioner, mBubbleController);
|
||||||
|
addView(mStackEduView);
|
||||||
|
mBubbleContainer.bringToFront(); // Stack appears on top of the stack education
|
||||||
|
mStackEduView.show(mPositioner.getDefaultStartPosition());
|
||||||
}
|
}
|
||||||
maybeShowManageEdu();
|
if (mManageEduView != null && mManageEduView.getVisibility() == VISIBLE) {
|
||||||
if (mStackEduView != null) {
|
removeView(mManageEduView);
|
||||||
mStackEduView.invalidate();
|
mManageEduView = new ManageEducationView(mContext, mPositioner);
|
||||||
|
addView(mManageEduView);
|
||||||
|
mManageEduView.show(mExpandedBubble.getExpandedView());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1274,6 +1277,7 @@ public class BubbleStackView extends FrameLayout
|
|||||||
setUpManageMenu();
|
setUpManageMenu();
|
||||||
setUpFlyout();
|
setUpFlyout();
|
||||||
setUpDismissView();
|
setUpDismissView();
|
||||||
|
updateUserEdu();
|
||||||
mBubbleSize = mPositioner.getBubbleSize();
|
mBubbleSize = mPositioner.getBubbleSize();
|
||||||
for (Bubble b : mBubbleData.getBubbles()) {
|
for (Bubble b : mBubbleData.getBubbles()) {
|
||||||
if (b.getIconView() == null) {
|
if (b.getIconView() == null) {
|
||||||
@@ -1730,6 +1734,21 @@ public class BubbleStackView extends FrameLayout
|
|||||||
notifyExpansionChanged(mExpandedBubble, mIsExpanded);
|
notifyExpansionChanged(mExpandedBubble, mIsExpanded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when back press occurs while bubbles are expanded.
|
||||||
|
*/
|
||||||
|
public void onBackPressed() {
|
||||||
|
if (mIsExpanded) {
|
||||||
|
if (mShowingManage) {
|
||||||
|
showManageMenu(false);
|
||||||
|
} else if (mManageEduView != null && mManageEduView.getVisibility() == VISIBLE) {
|
||||||
|
mManageEduView.hide();
|
||||||
|
} else {
|
||||||
|
setExpanded(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setBubbleVisibility(Bubble b, boolean visible) {
|
void setBubbleVisibility(Bubble b, boolean visible) {
|
||||||
if (b.getIconView() != null) {
|
if (b.getIconView() != null) {
|
||||||
b.getIconView().setVisibility(visible ? VISIBLE : GONE);
|
b.getIconView().setVisibility(visible ? VISIBLE : GONE);
|
||||||
@@ -1955,6 +1974,9 @@ public class BubbleStackView extends FrameLayout
|
|||||||
private void animateCollapse() {
|
private void animateCollapse() {
|
||||||
cancelDelayedExpandCollapseSwitchAnimations();
|
cancelDelayedExpandCollapseSwitchAnimations();
|
||||||
|
|
||||||
|
if (mManageEduView != null && mManageEduView.getVisibility() == VISIBLE) {
|
||||||
|
mManageEduView.hide();
|
||||||
|
}
|
||||||
// Hide the menu if it's visible.
|
// Hide the menu if it's visible.
|
||||||
showManageMenu(false);
|
showManageMenu(false);
|
||||||
|
|
||||||
@@ -2032,7 +2054,7 @@ public class BubbleStackView extends FrameLayout
|
|||||||
final BubbleViewProvider previouslySelected = mExpandedBubble;
|
final BubbleViewProvider previouslySelected = mExpandedBubble;
|
||||||
beforeExpandedViewAnimation();
|
beforeExpandedViewAnimation();
|
||||||
if (mManageEduView != null) {
|
if (mManageEduView != null) {
|
||||||
mManageEduView.hide(false /* fromExpansion */);
|
mManageEduView.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DEBUG_BUBBLE_STACK_VIEW) {
|
if (DEBUG_BUBBLE_STACK_VIEW) {
|
||||||
|
|||||||
@@ -18,12 +18,13 @@ package com.android.wm.shell.bubbles
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
|
import android.graphics.drawable.ColorDrawable
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
import android.widget.Button
|
import android.widget.Button
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import com.android.internal.R.color.system_neutral1_900
|
||||||
import com.android.internal.util.ContrastColorUtil
|
|
||||||
import com.android.wm.shell.R
|
import com.android.wm.shell.R
|
||||||
import com.android.wm.shell.animation.Interpolators
|
import com.android.wm.shell.animation.Interpolators
|
||||||
|
|
||||||
@@ -31,21 +32,22 @@ import com.android.wm.shell.animation.Interpolators
|
|||||||
* User education view to highlight the manage button that allows a user to configure the settings
|
* User education view to highlight the manage button that allows a user to configure the settings
|
||||||
* for the bubble. Shown only the first time a user expands a bubble.
|
* for the bubble. Shown only the first time a user expands a bubble.
|
||||||
*/
|
*/
|
||||||
class ManageEducationView constructor(context: Context) : LinearLayout(context) {
|
class ManageEducationView constructor(context: Context, positioner: BubblePositioner)
|
||||||
|
: LinearLayout(context) {
|
||||||
|
|
||||||
private val TAG = if (BubbleDebugConfig.TAG_WITH_CLASS_NAME) "BubbleManageEducationView"
|
private val TAG = if (BubbleDebugConfig.TAG_WITH_CLASS_NAME) "ManageEducationView"
|
||||||
else BubbleDebugConfig.TAG_BUBBLES
|
else BubbleDebugConfig.TAG_BUBBLES
|
||||||
|
|
||||||
private val ANIMATE_DURATION: Long = 200
|
private val ANIMATE_DURATION: Long = 200
|
||||||
private val ANIMATE_DURATION_SHORT: Long = 40
|
|
||||||
|
|
||||||
private val manageView by lazy { findViewById<View>(R.id.manage_education_view) }
|
private val positioner: BubblePositioner = positioner
|
||||||
private val manageButton by lazy { findViewById<Button>(R.id.manage) }
|
private val manageView by lazy { findViewById<ViewGroup>(R.id.manage_education_view) }
|
||||||
|
private val manageButton by lazy { findViewById<Button>(R.id.manage_button) }
|
||||||
private val gotItButton by lazy { findViewById<Button>(R.id.got_it) }
|
private val gotItButton by lazy { findViewById<Button>(R.id.got_it) }
|
||||||
private val titleTextView by lazy { findViewById<TextView>(R.id.user_education_title) }
|
|
||||||
private val descTextView by lazy { findViewById<TextView>(R.id.user_education_description) }
|
|
||||||
|
|
||||||
private var isHiding = false
|
private var isHiding = false
|
||||||
|
private var realManageButtonRect = Rect()
|
||||||
|
private var bubbleExpandedView: BubbleExpandedView? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
LayoutInflater.from(context).inflate(R.layout.bubbles_manage_button_education, this)
|
LayoutInflater.from(context).inflate(R.layout.bubbles_manage_button_education, this)
|
||||||
@@ -66,18 +68,17 @@ class ManageEducationView constructor(context: Context) : LinearLayout(context)
|
|||||||
override fun onFinishInflate() {
|
override fun onFinishInflate() {
|
||||||
super.onFinishInflate()
|
super.onFinishInflate()
|
||||||
layoutDirection = resources.configuration.layoutDirection
|
layoutDirection = resources.configuration.layoutDirection
|
||||||
setTextColor()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setTextColor() {
|
private fun setButtonColor() {
|
||||||
val typedArray = mContext.obtainStyledAttributes(intArrayOf(android.R.attr.colorAccent,
|
val typedArray = mContext.obtainStyledAttributes(intArrayOf(
|
||||||
android.R.attr.textColorPrimaryInverse))
|
com.android.internal.R.attr.colorAccentPrimary))
|
||||||
val bgColor = typedArray.getColor(0 /* index */, Color.BLACK)
|
val buttonColor = typedArray.getColor(0 /* index */, Color.TRANSPARENT)
|
||||||
var textColor = typedArray.getColor(1 /* index */, Color.WHITE)
|
|
||||||
typedArray.recycle()
|
typedArray.recycle()
|
||||||
textColor = ContrastColorUtil.ensureTextContrast(textColor, bgColor, true)
|
|
||||||
titleTextView.setTextColor(textColor)
|
manageButton.setTextColor(mContext.getColor(system_neutral1_900))
|
||||||
descTextView.setTextColor(textColor)
|
manageButton.setBackgroundDrawable(ColorDrawable(buttonColor))
|
||||||
|
gotItButton.setBackgroundDrawable(ColorDrawable(buttonColor))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setDrawableDirection() {
|
private fun setDrawableDirection() {
|
||||||
@@ -91,30 +92,39 @@ class ManageEducationView constructor(context: Context) : LinearLayout(context)
|
|||||||
* If necessary, toggles the user education view for the manage button. This is shown when the
|
* If necessary, toggles the user education view for the manage button. This is shown when the
|
||||||
* bubble stack is expanded for the first time.
|
* bubble stack is expanded for the first time.
|
||||||
*
|
*
|
||||||
* @param show whether the user education view should show or not.
|
* @param expandedView the expandedView the user education is shown on top of.
|
||||||
*/
|
*/
|
||||||
fun show(expandedView: BubbleExpandedView, rect: Rect) {
|
fun show(expandedView: BubbleExpandedView) {
|
||||||
|
setButtonColor()
|
||||||
if (visibility == VISIBLE) return
|
if (visibility == VISIBLE) return
|
||||||
|
|
||||||
|
bubbleExpandedView = expandedView
|
||||||
|
expandedView.taskView?.setObscuredTouchRect(Rect(positioner.screenRect))
|
||||||
|
|
||||||
|
layoutParams.width = if (positioner.isLargeScreen)
|
||||||
|
context.resources.getDimensionPixelSize(
|
||||||
|
R.dimen.bubbles_user_education_width_large_screen)
|
||||||
|
else ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
|
||||||
alpha = 0f
|
alpha = 0f
|
||||||
visibility = View.VISIBLE
|
visibility = View.VISIBLE
|
||||||
|
expandedView.getManageButtonBoundsOnScreen(realManageButtonRect)
|
||||||
|
manageView.setPadding(realManageButtonRect.left - expandedView.manageButtonMargin,
|
||||||
|
manageView.paddingTop, manageView.paddingRight, manageView.paddingBottom)
|
||||||
post {
|
post {
|
||||||
expandedView.getManageButtonBoundsOnScreen(rect)
|
|
||||||
|
|
||||||
manageButton
|
manageButton
|
||||||
.setOnClickListener {
|
.setOnClickListener {
|
||||||
expandedView.findViewById<View>(R.id.settings_button).performClick()
|
hide()
|
||||||
hide(true /* isStackExpanding */)
|
expandedView.findViewById<View>(R.id.manage_button).performClick()
|
||||||
}
|
}
|
||||||
gotItButton.setOnClickListener { hide(true /* isStackExpanding */) }
|
gotItButton.setOnClickListener { hide() }
|
||||||
setOnClickListener { hide(true /* isStackExpanding */) }
|
setOnClickListener { hide() }
|
||||||
|
|
||||||
with(manageView) {
|
val offsetViewBounds = Rect()
|
||||||
translationX = 0f
|
manageButton.getDrawingRect(offsetViewBounds)
|
||||||
val inset = resources.getDimensionPixelSize(
|
manageView.offsetDescendantRectToMyCoords(manageButton, offsetViewBounds)
|
||||||
R.dimen.bubbles_manage_education_top_inset)
|
translationX = 0f
|
||||||
translationY = (rect.top - manageView.height + inset).toFloat()
|
translationY = (realManageButtonRect.top - offsetViewBounds.top).toFloat()
|
||||||
}
|
|
||||||
bringToFront()
|
bringToFront()
|
||||||
animate()
|
animate()
|
||||||
.setDuration(ANIMATE_DURATION)
|
.setDuration(ANIMATE_DURATION)
|
||||||
@@ -124,13 +134,14 @@ class ManageEducationView constructor(context: Context) : LinearLayout(context)
|
|||||||
setShouldShow(false)
|
setShouldShow(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hide(isStackExpanding: Boolean) {
|
fun hide() {
|
||||||
|
bubbleExpandedView?.taskView?.setObscuredTouchRect(null)
|
||||||
if (visibility != VISIBLE || isHiding) return
|
if (visibility != VISIBLE || isHiding) return
|
||||||
|
|
||||||
animate()
|
animate()
|
||||||
.withStartAction { isHiding = true }
|
.withStartAction { isHiding = true }
|
||||||
.alpha(0f)
|
.alpha(0f)
|
||||||
.setDuration(if (isStackExpanding) ANIMATE_DURATION_SHORT else ANIMATE_DURATION)
|
.setDuration(ANIMATE_DURATION)
|
||||||
.withEndAction {
|
.withEndAction {
|
||||||
isHiding = false
|
isHiding = false
|
||||||
visibility = GONE
|
visibility = GONE
|
||||||
|
|||||||
@@ -18,8 +18,11 @@ package com.android.wm.shell.bubbles
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.PointF
|
import android.graphics.PointF
|
||||||
|
import android.view.KeyEvent
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.View.OnKeyListener
|
||||||
|
import android.view.ViewGroup
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import com.android.internal.util.ContrastColorUtil
|
import com.android.internal.util.ContrastColorUtil
|
||||||
@@ -30,7 +33,12 @@ import com.android.wm.shell.animation.Interpolators
|
|||||||
* User education view to highlight the collapsed stack of bubbles.
|
* User education view to highlight the collapsed stack of bubbles.
|
||||||
* Shown only the first time a user taps the stack.
|
* Shown only the first time a user taps the stack.
|
||||||
*/
|
*/
|
||||||
class StackEducationView constructor(context: Context) : LinearLayout(context) {
|
class StackEducationView constructor(
|
||||||
|
context: Context,
|
||||||
|
positioner: BubblePositioner,
|
||||||
|
controller: BubbleController
|
||||||
|
)
|
||||||
|
: LinearLayout(context) {
|
||||||
|
|
||||||
private val TAG = if (BubbleDebugConfig.TAG_WITH_CLASS_NAME) "BubbleStackEducationView"
|
private val TAG = if (BubbleDebugConfig.TAG_WITH_CLASS_NAME) "BubbleStackEducationView"
|
||||||
else BubbleDebugConfig.TAG_BUBBLES
|
else BubbleDebugConfig.TAG_BUBBLES
|
||||||
@@ -38,6 +46,9 @@ class StackEducationView constructor(context: Context) : LinearLayout(context) {
|
|||||||
private val ANIMATE_DURATION: Long = 200
|
private val ANIMATE_DURATION: Long = 200
|
||||||
private val ANIMATE_DURATION_SHORT: Long = 40
|
private val ANIMATE_DURATION_SHORT: Long = 40
|
||||||
|
|
||||||
|
private val positioner: BubblePositioner = positioner
|
||||||
|
private val controller: BubbleController = controller
|
||||||
|
|
||||||
private val view by lazy { findViewById<View>(R.id.stack_education_layout) }
|
private val view by lazy { findViewById<View>(R.id.stack_education_layout) }
|
||||||
private val titleTextView by lazy { findViewById<TextView>(R.id.stack_education_title) }
|
private val titleTextView by lazy { findViewById<TextView>(R.id.stack_education_title) }
|
||||||
private val descTextView by lazy { findViewById<TextView>(R.id.stack_education_description) }
|
private val descTextView by lazy { findViewById<TextView>(R.id.stack_education_description) }
|
||||||
@@ -67,6 +78,28 @@ class StackEducationView constructor(context: Context) : LinearLayout(context) {
|
|||||||
setTextColor()
|
setTextColor()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onAttachedToWindow() {
|
||||||
|
super.onAttachedToWindow()
|
||||||
|
setFocusableInTouchMode(true)
|
||||||
|
setOnKeyListener(object : OnKeyListener {
|
||||||
|
override fun onKey(v: View?, keyCode: Int, event: KeyEvent): Boolean {
|
||||||
|
// if the event is a key down event on the enter button
|
||||||
|
if (event.action == KeyEvent.ACTION_UP &&
|
||||||
|
keyCode == KeyEvent.KEYCODE_BACK && !isHiding) {
|
||||||
|
hide(false)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDetachedFromWindow() {
|
||||||
|
super.onDetachedFromWindow()
|
||||||
|
setOnKeyListener(null)
|
||||||
|
controller.updateWindowFlagsForBackpress(false /* interceptBack */)
|
||||||
|
}
|
||||||
|
|
||||||
private fun setTextColor() {
|
private fun setTextColor() {
|
||||||
val ta = mContext.obtainStyledAttributes(intArrayOf(android.R.attr.colorAccent,
|
val ta = mContext.obtainStyledAttributes(intArrayOf(android.R.attr.colorAccent,
|
||||||
android.R.attr.textColorPrimaryInverse))
|
android.R.attr.textColorPrimaryInverse))
|
||||||
@@ -94,13 +127,25 @@ class StackEducationView constructor(context: Context) : LinearLayout(context) {
|
|||||||
fun show(stackPosition: PointF): Boolean {
|
fun show(stackPosition: PointF): Boolean {
|
||||||
if (visibility == VISIBLE) return false
|
if (visibility == VISIBLE) return false
|
||||||
|
|
||||||
|
controller.updateWindowFlagsForBackpress(true /* interceptBack */)
|
||||||
|
layoutParams.width = if (positioner.isLargeScreen)
|
||||||
|
context.resources.getDimensionPixelSize(
|
||||||
|
R.dimen.bubbles_user_education_width_large_screen)
|
||||||
|
else ViewGroup.LayoutParams.MATCH_PARENT
|
||||||
|
|
||||||
setAlpha(0f)
|
setAlpha(0f)
|
||||||
setVisibility(View.VISIBLE)
|
setVisibility(View.VISIBLE)
|
||||||
post {
|
post {
|
||||||
|
requestFocus()
|
||||||
with(view) {
|
with(view) {
|
||||||
val bubbleSize = context.resources.getDimensionPixelSize(
|
if (resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_LTR) {
|
||||||
R.dimen.bubble_size)
|
setPadding(positioner.bubbleSize + paddingRight, paddingTop, paddingRight,
|
||||||
translationY = stackPosition.y + bubbleSize / 2 - getHeight() / 2
|
paddingBottom)
|
||||||
|
} else {
|
||||||
|
setPadding(paddingLeft, paddingTop, positioner.bubbleSize + paddingLeft,
|
||||||
|
paddingBottom)
|
||||||
|
}
|
||||||
|
translationY = stackPosition.y + positioner.bubbleSize / 2 - getHeight() / 2
|
||||||
}
|
}
|
||||||
animate()
|
animate()
|
||||||
.setDuration(ANIMATE_DURATION)
|
.setDuration(ANIMATE_DURATION)
|
||||||
@@ -114,15 +159,16 @@ class StackEducationView constructor(context: Context) : LinearLayout(context) {
|
|||||||
/**
|
/**
|
||||||
* If necessary, hides the stack education view.
|
* If necessary, hides the stack education view.
|
||||||
*
|
*
|
||||||
* @param fromExpansion if true this indicates the hide is happening due to the bubble being
|
* @param isExpanding if true this indicates the hide is happening due to the bubble being
|
||||||
* expanded, false if due to a touch outside of the bubble stack.
|
* expanded, false if due to a touch outside of the bubble stack.
|
||||||
*/
|
*/
|
||||||
fun hide(fromExpansion: Boolean) {
|
fun hide(isExpanding: Boolean) {
|
||||||
if (visibility != VISIBLE || isHiding) return
|
if (visibility != VISIBLE || isHiding) return
|
||||||
|
|
||||||
|
controller.updateWindowFlagsForBackpress(false /* interceptBack */)
|
||||||
animate()
|
animate()
|
||||||
.alpha(0f)
|
.alpha(0f)
|
||||||
.setDuration(if (fromExpansion) ANIMATE_DURATION_SHORT else ANIMATE_DURATION)
|
.setDuration(if (isExpanding) ANIMATE_DURATION_SHORT else ANIMATE_DURATION)
|
||||||
.withEndAction { visibility = GONE }
|
.withEndAction { visibility = GONE }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user