Merge changes I60f2bedb,Ie0e3647b,I1c77a810 into sc-v2-dev
* changes: Fix up back press with bubbles manage menu or user education Fix touches activating TaskView when showing user education Updates to user education for large screen
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