Move manage menu user education into subview
Bug: 161939484 Test: force manage edu to show, press both buttons, force rtl, press both buttons again, keep using bubbles normally, no regressions Change-Id: If9ddb75322e0a57358616704e6282619fc963857
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<com.android.systemui.bubbles.BubbleManageEducationView
|
||||
<com.android.systemui.bubbles.ManageEducationView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
@@ -87,4 +87,4 @@
|
||||
/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</com.android.systemui.bubbles.BubbleManageEducationView>
|
||||
</com.android.systemui.bubbles.ManageEducationView>
|
||||
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
* 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.bubbles;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Color;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.util.ContrastColorUtil;
|
||||
import com.android.systemui.R;
|
||||
|
||||
/**
|
||||
* Educational 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.
|
||||
*/
|
||||
public class BubbleManageEducationView extends LinearLayout {
|
||||
|
||||
private View mManageView;
|
||||
private TextView mTitleTextView;
|
||||
private TextView mDescTextView;
|
||||
|
||||
public BubbleManageEducationView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public BubbleManageEducationView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public BubbleManageEducationView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public BubbleManageEducationView(Context context, AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
|
||||
mManageView = findViewById(R.id.manage_education_view);
|
||||
mTitleTextView = findViewById(R.id.user_education_title);
|
||||
mDescTextView = findViewById(R.id.user_education_description);
|
||||
|
||||
final TypedArray ta = mContext.obtainStyledAttributes(
|
||||
new int[] {android.R.attr.colorAccent,
|
||||
android.R.attr.textColorPrimaryInverse});
|
||||
final int bgColor = ta.getColor(0, Color.BLACK);
|
||||
int textColor = ta.getColor(1, Color.WHITE);
|
||||
ta.recycle();
|
||||
|
||||
textColor = ContrastColorUtil.ensureTextContrast(textColor, bgColor, true);
|
||||
mTitleTextView.setTextColor(textColor);
|
||||
mDescTextView.setTextColor(textColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the position for the manage view.
|
||||
*/
|
||||
public void setManageViewPosition(int x, int y) {
|
||||
mManageView.setTranslationX(x);
|
||||
mManageView.setTranslationY(y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the height of the view that shows the educational text and pointer.
|
||||
*/
|
||||
public int getManageViewHeight() {
|
||||
return mManageView.getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLayoutDirection(int direction) {
|
||||
super.setLayoutDirection(direction);
|
||||
if (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
|
||||
mManageView.setBackgroundResource(R.drawable.bubble_stack_user_education_bg_rtl);
|
||||
mTitleTextView.setGravity(Gravity.RIGHT);
|
||||
mDescTextView.setGravity(Gravity.RIGHT);
|
||||
} else {
|
||||
mManageView.setBackgroundResource(R.drawable.bubble_stack_user_education_bg);
|
||||
mTitleTextView.setGravity(Gravity.LEFT);
|
||||
mDescTextView.setGravity(Gravity.LEFT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,7 @@ public class BubbleStackView extends FrameLayout
|
||||
private static final String TAG = TAG_WITH_CLASS_NAME ? "BubbleStackView" : TAG_BUBBLES;
|
||||
|
||||
/** Animation durations for bubble stack user education views. **/
|
||||
private static final int ANIMATE_STACK_USER_EDUCATION_DURATION = 200;
|
||||
static final int ANIMATE_STACK_USER_EDUCATION_DURATION = 200;
|
||||
private static final int ANIMATE_STACK_USER_EDUCATION_DURATION_SHORT = 40;
|
||||
|
||||
/** How far the flyout needs to be dragged before it's dismissed regardless of velocity. */
|
||||
@@ -748,7 +748,7 @@ public class BubbleStackView extends FrameLayout
|
||||
private View mUserEducationView;
|
||||
|
||||
private boolean mShouldShowManageEducation;
|
||||
private BubbleManageEducationView mManageEducationView;
|
||||
private ManageEducationView mManageEducationView;
|
||||
private boolean mAnimatingManageEducationAway;
|
||||
|
||||
private ViewGroup mManageMenu;
|
||||
@@ -1135,12 +1135,9 @@ public class BubbleStackView extends FrameLayout
|
||||
Log.d(TAG, "shouldShowManageEducation: " + mShouldShowManageEducation);
|
||||
}
|
||||
if (mShouldShowManageEducation) {
|
||||
mManageEducationView = (BubbleManageEducationView)
|
||||
mInflater.inflate(R.layout.bubbles_manage_button_education, this,
|
||||
mManageEducationView = (ManageEducationView)
|
||||
mInflater.inflate(R.layout.bubbles_manage_button_education, this /* root */,
|
||||
false /* attachToRoot */);
|
||||
mManageEducationView.setVisibility(GONE);
|
||||
mManageEducationView.setElevation(mBubbleElevation);
|
||||
mManageEducationView.setLayoutDirection(View.LAYOUT_DIRECTION_LOCALE);
|
||||
addView(mManageEducationView);
|
||||
}
|
||||
}
|
||||
@@ -1753,28 +1750,8 @@ public class BubbleStackView extends FrameLayout
|
||||
&& mManageEducationView.getVisibility() != VISIBLE
|
||||
&& mIsExpanded
|
||||
&& mExpandedBubble.getExpandedView() != null) {
|
||||
mManageEducationView.setAlpha(0);
|
||||
mManageEducationView.setVisibility(VISIBLE);
|
||||
mManageEducationView.post(() -> {
|
||||
mExpandedBubble.getExpandedView().getManageButtonBoundsOnScreen(mTempRect);
|
||||
final int viewHeight = mManageEducationView.getManageViewHeight();
|
||||
final int inset = getResources().getDimensionPixelSize(
|
||||
R.dimen.bubbles_manage_education_top_inset);
|
||||
mManageEducationView.bringToFront();
|
||||
mManageEducationView.setManageViewPosition(0, mTempRect.top - viewHeight + inset);
|
||||
mManageEducationView.animate()
|
||||
.setDuration(ANIMATE_STACK_USER_EDUCATION_DURATION)
|
||||
.setInterpolator(FAST_OUT_SLOW_IN).alpha(1);
|
||||
mManageEducationView.findViewById(R.id.manage).setOnClickListener(view -> {
|
||||
mExpandedBubble.getExpandedView().findViewById(R.id.settings_button)
|
||||
.performClick();
|
||||
maybeShowManageEducation(false);
|
||||
});
|
||||
mManageEducationView.findViewById(R.id.got_it).setOnClickListener(view ->
|
||||
maybeShowManageEducation(false));
|
||||
mManageEducationView.setOnClickListener(view ->
|
||||
maybeShowManageEducation(false));
|
||||
});
|
||||
mManageEducationView.show(mExpandedBubble.getExpandedView(), mTempRect,
|
||||
() -> maybeShowManageEducation(false) /* run on click */);
|
||||
Prefs.putBoolean(getContext(), HAS_SEEN_BUBBLES_MANAGE_EDUCATION, true);
|
||||
} else if (!show
|
||||
&& mManageEducationView.getVisibility() == VISIBLE
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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.bubbles
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.graphics.Rect
|
||||
import android.util.AttributeSet
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.widget.Button
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.android.internal.util.ContrastColorUtil
|
||||
import com.android.systemui.Interpolators
|
||||
import com.android.systemui.R
|
||||
|
||||
/**
|
||||
* Educational 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.
|
||||
*/
|
||||
class ManageEducationView @JvmOverloads constructor(
|
||||
context: Context?,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0,
|
||||
defStyleRes: Int = 0
|
||||
) : LinearLayout(context, attrs, defStyleAttr, defStyleRes) {
|
||||
|
||||
private val manageView by lazy { findViewById<View>(R.id.manage_education_view) }
|
||||
private val manageButton by lazy { findViewById<Button>(R.id.manage) }
|
||||
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 isInflated = false
|
||||
|
||||
init {
|
||||
this.visibility = View.GONE
|
||||
this.elevation = resources.getDimensionPixelSize(R.dimen.bubble_elevation).toFloat()
|
||||
this.layoutDirection = View.LAYOUT_DIRECTION_LOCALE
|
||||
}
|
||||
|
||||
override fun setLayoutDirection(direction: Int) {
|
||||
super.setLayoutDirection(direction)
|
||||
// setLayoutDirection runs before onFinishInflate
|
||||
// so skip if views haven't inflated; otherwise we'll get NPEs
|
||||
if (!isInflated) return
|
||||
setDirection()
|
||||
}
|
||||
|
||||
override fun onFinishInflate() {
|
||||
super.onFinishInflate()
|
||||
isInflated = true
|
||||
setDirection()
|
||||
setTextColor()
|
||||
}
|
||||
|
||||
private fun setTextColor() {
|
||||
val typedArray = mContext.obtainStyledAttributes(intArrayOf(android.R.attr.colorAccent,
|
||||
android.R.attr.textColorPrimaryInverse))
|
||||
val bgColor = typedArray.getColor(0 /* index */, Color.BLACK)
|
||||
var textColor = typedArray.getColor(1 /* index */, Color.WHITE)
|
||||
typedArray.recycle()
|
||||
textColor = ContrastColorUtil.ensureTextContrast(textColor, bgColor, true)
|
||||
titleTextView.setTextColor(textColor)
|
||||
descTextView.setTextColor(textColor)
|
||||
}
|
||||
|
||||
fun setDirection() {
|
||||
manageView.setBackgroundResource(
|
||||
if (resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL)
|
||||
R.drawable.bubble_stack_user_education_bg_rtl
|
||||
else R.drawable.bubble_stack_user_education_bg)
|
||||
titleTextView.gravity = Gravity.START
|
||||
descTextView.gravity = Gravity.START
|
||||
}
|
||||
|
||||
fun show(expandedView: BubbleExpandedView, rect : Rect, hideMenu: Runnable) {
|
||||
alpha = 0f
|
||||
visibility = View.VISIBLE
|
||||
post {
|
||||
expandedView.getManageButtonBoundsOnScreen(rect)
|
||||
with(hideMenu) {
|
||||
manageButton
|
||||
.setOnClickListener {
|
||||
expandedView.findViewById<View>(R.id.settings_button).performClick()
|
||||
this.run()
|
||||
}
|
||||
gotItButton.setOnClickListener { this.run() }
|
||||
setOnClickListener { this.run() }
|
||||
}
|
||||
with(manageView) {
|
||||
translationX = 0f
|
||||
val inset = resources.getDimensionPixelSize(
|
||||
R.dimen.bubbles_manage_education_top_inset)
|
||||
translationY = (rect.top - manageView.height + inset).toFloat()
|
||||
}
|
||||
bringToFront()
|
||||
animate()
|
||||
.setDuration(BubbleStackView.ANIMATE_STACK_USER_EDUCATION_DURATION.toLong())
|
||||
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
|
||||
.alpha(1f)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user