Merge changes from topic "AddWorkSchedulerInWorkProfileFlag" into main
* changes:
Add work_scheduler_in_work_profile flag.
Remove layoutTransitions for current FAB and use custom animation.
diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig
index 6ff3bb2..5373147 100644
--- a/aconfig/launcher.aconfig
+++ b/aconfig/launcher.aconfig
@@ -369,6 +369,13 @@
}
flag {
+ name: "work_scheduler_in_work_profile"
+ namespace: "launcher"
+ description: "Enables work scheduler view above the work pause button in work profile."
+ bug: "361589193"
+}
+
+flag {
name: "one_grid_specs"
namespace: "launcher"
description: "Defines the new specs for grids based on OneGrid"
diff --git a/res/drawable/work_mode_fab_background.xml b/res/drawable/work_mode_fab_background.xml
index 6be33e8..fd948d1 100644
--- a/res/drawable/work_mode_fab_background.xml
+++ b/res/drawable/work_mode_fab_background.xml
@@ -19,6 +19,9 @@
<shape android:shape="rectangle">
<corners android:radius="@dimen/work_fab_radius" />
<solid android:color="@color/work_fab_bg_color" />
+ <padding
+ android:left="@dimen/work_mode_fab_background_horizontal_padding"
+ android:right="@dimen/work_mode_fab_background_horizontal_padding"/>
</shape>
</item>
</ripple>
diff --git a/res/layout/work_mode_fab.xml b/res/layout/work_mode_fab.xml
index b3484c9..fc59e56 100644
--- a/res/layout/work_mode_fab.xml
+++ b/res/layout/work_mode_fab.xml
@@ -23,18 +23,16 @@
android:gravity="center_vertical"
android:background="@drawable/work_mode_fab_background"
android:forceHasOverlappingRendering="false"
- android:contentDescription="@string/work_apps_pause_btn_text"
- android:paddingStart="@dimen/work_mode_fab_background_start_padding"
- android:paddingEnd="@dimen/work_mode_fab_background_end_padding"
- android:animateLayoutChanges="true">
+ android:contentDescription="@string/work_apps_pause_btn_text">
<ImageView
android:id="@+id/work_icon"
android:layout_width="@dimen/work_fab_icon_size"
android:layout_height="@dimen/work_fab_icon_size"
+ android:layout_marginVertical="@dimen/work_fab_icon_vertical_margin"
android:importantForAccessibility="no"
- android:layout_marginEnd="@dimen/work_fab_icon_end_margin"
android:src="@drawable/ic_corp_off"
android:tint="@color/work_fab_icon_color"
+ android:layout_marginStart="@dimen/work_fab_icon_start_margin_expanded"
android:scaleType="center"/>
<TextView
android:id="@+id/pause_text"
@@ -46,8 +44,8 @@
android:includeFontPadding="false"
android:textDirection="locale"
android:text="@string/work_apps_pause_btn_text"
+ android:layout_marginStart="@dimen/work_fab_text_start_margin"
android:layout_marginEnd="@dimen/work_fab_text_end_margin"
- android:ellipsize="end"
android:maxLines="1"
style="@style/TextHeadline"/>
</com.android.launcher3.allapps.WorkModeSwitch>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 731e24e..037687d 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -156,15 +156,16 @@
<dimen name="work_fab_height">56dp</dimen>
<dimen name="work_fab_radius">16dp</dimen>
<dimen name="work_fab_icon_size">24dp</dimen>
- <dimen name="work_fab_icon_end_margin">12dp</dimen>
- <dimen name="work_fab_text_end_margin">16dp</dimen>
+ <dimen name="work_fab_icon_vertical_margin">16dp</dimen>
+ <dimen name="work_fab_icon_start_margin_expanded">4dp</dimen>
+ <dimen name="work_fab_text_start_margin">8dp</dimen>
+ <dimen name="work_fab_text_end_margin">10dp</dimen>
<dimen name="work_card_padding_horizontal">10dp</dimen>
<dimen name="work_fab_width">214dp</dimen>
<dimen name="work_card_button_height">52dp</dimen>
<dimen name="work_fab_margin">16dp</dimen>
<dimen name="work_fab_margin_bottom">20dp</dimen>
- <dimen name="work_mode_fab_background_start_padding">16dp</dimen>
- <dimen name="work_mode_fab_background_end_padding">4dp</dimen>
+ <dimen name="work_mode_fab_background_horizontal_padding">16dp</dimen>
<dimen name="work_profile_footer_padding">20dp</dimen>
<dimen name="work_edu_card_margin">16dp</dimen>
<dimen name="work_edu_card_radius">16dp</dimen>
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index 6049574..f1f72b2 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -15,10 +15,18 @@
*/
package com.android.launcher3.allapps;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Rect;
+import android.text.TextUtils;
import android.util.AttributeSet;
+import android.view.ViewGroup;
import android.view.WindowInsets;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -26,10 +34,12 @@
import androidx.core.graphics.Insets;
import androidx.core.view.WindowInsetsCompat;
+import com.android.app.animation.Interpolators;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.AnimatedPropertySetter;
import com.android.launcher3.anim.KeyboardInsetAnimationCallback;
import com.android.launcher3.model.StringCache;
import com.android.launcher3.views.ActivityContext;
@@ -39,9 +49,14 @@
public class WorkModeSwitch extends LinearLayout implements Insettable,
KeyboardInsetAnimationCallback.KeyboardInsetListener {
+ private static final int TEXT_EXPAND_OPACITY_DURATION = 300;
+ private static final int TEXT_COLLAPSE_OPACITY_DURATION = 50;
+ private static final int EXPAND_COLLAPSE_DURATION = 300;
+ private static final int TEXT_ALPHA_EXPAND_DELAY = 80;
+ private static final int TEXT_ALPHA_COLLAPSE_DELAY = 0;
private static final int FLAG_FADE_ONGOING = 1 << 1;
private static final int FLAG_TRANSLATION_ONGOING = 1 << 2;
- private static final int FLAG_PROFILE_TOGGLE_ONGOING = 1 << 3;
+ private static final int FLAG_IS_EXPAND = 1 << 3;
private static final int SCROLL_THRESHOLD_DP = 10;
private final Rect mInsets = new Rect();
@@ -49,11 +64,15 @@
private int mFlags;
private final ActivityContext mActivityContext;
private final Context mContext;
+ private final int mTextMarginStart;
+ private final int mTextMarginEnd;
+ private final int mIconMarginStart;
// Threshold when user scrolls up/down to determine when should button extend/collapse
private final int mScrollThreshold;
private TextView mTextView;
-
+ private ImageView mIcon;
+ private ValueAnimator mPauseFABAnim;
public WorkModeSwitch(@NonNull Context context) {
this(context, null, 0);
@@ -68,6 +87,12 @@
mContext = context;
mScrollThreshold = Utilities.dpToPx(SCROLL_THRESHOLD_DP);
mActivityContext = ActivityContext.lookupContext(getContext());
+ mTextMarginStart = mContext.getResources().getDimensionPixelSize(
+ R.dimen.work_fab_text_start_margin);
+ mTextMarginEnd = mContext.getResources().getDimensionPixelSize(
+ R.dimen.work_fab_text_end_margin);
+ mIconMarginStart = mContext.getResources().getDimensionPixelSize(
+ R.dimen.work_fab_icon_start_margin_expanded);
}
@Override
@@ -75,11 +100,13 @@
super.onFinishInflate();
mTextView = findViewById(R.id.pause_text);
+ mIcon = findViewById(R.id.work_icon);
setSelected(true);
KeyboardInsetAnimationCallback keyboardInsetAnimationCallback =
new KeyboardInsetAnimationCallback(this);
setWindowInsetsAnimationCallback(keyboardInsetAnimationCallback);
-
+ // Expand is the default state upon initialization.
+ addFlag(FLAG_IS_EXPAND);
setInsets(mActivityContext.getDeviceProfile().getInsets());
updateStringFromCache();
}
@@ -114,18 +141,18 @@
@Override
public boolean isEnabled() {
- return super.isEnabled() && getVisibility() == VISIBLE && mFlags == 0;
+ return super.isEnabled() && getVisibility() == VISIBLE;
}
public void animateVisibility(boolean visible) {
clearAnimation();
if (visible) {
- setFlag(FLAG_FADE_ONGOING);
+ addFlag(FLAG_FADE_ONGOING);
setVisibility(VISIBLE);
extend();
animate().alpha(1).withEndAction(() -> removeFlag(FLAG_FADE_ONGOING)).start();
} else if (getVisibility() != GONE) {
- setFlag(FLAG_FADE_ONGOING);
+ addFlag(FLAG_FADE_ONGOING);
animate().alpha(0).withEndAction(() -> {
removeFlag(FLAG_FADE_ONGOING);
setVisibility(GONE);
@@ -156,6 +183,79 @@
super.setTranslationY(Math.min(translationY, -mInsets.bottom));
}
+
+ private void animatePillTransition(boolean isExpanding) {
+ if (!shouldAnimate(isExpanding)) {
+ return;
+ }
+ AnimatorSet animatorSet = new AnimatedPropertySetter().buildAnim();
+ mTextView.measure(0,0);
+ int currentWidth = mTextView.getWidth();
+ int fullWidth = mTextView.getMeasuredWidth();
+ float from = isExpanding ? 0 : currentWidth;
+ float to = isExpanding ? fullWidth : 0;
+ mPauseFABAnim = ObjectAnimator.ofFloat(from, to);
+ mPauseFABAnim.setDuration(EXPAND_COLLAPSE_DURATION);
+ mPauseFABAnim.setInterpolator(Interpolators.STANDARD);
+ mPauseFABAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ float translation = (float) valueAnimator.getAnimatedValue();
+ float translationFraction = translation / fullWidth;
+ ViewGroup.MarginLayoutParams textViewLayoutParams =
+ (ViewGroup.MarginLayoutParams) mTextView.getLayoutParams();
+ textViewLayoutParams.width = (int) translation;
+ textViewLayoutParams.setMarginStart((int) (mTextMarginStart * translationFraction));
+ textViewLayoutParams.setMarginEnd((int) (mTextMarginEnd * translationFraction));
+ mTextView.setLayoutParams(textViewLayoutParams);
+ ViewGroup.MarginLayoutParams iconLayoutParams =
+ (ViewGroup.MarginLayoutParams) mIcon.getLayoutParams();
+ iconLayoutParams.setMarginStart((int) (mIconMarginStart * translationFraction));
+ mIcon.setLayoutParams(iconLayoutParams);
+ }
+ });
+ mPauseFABAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ if (isExpanding) {
+ addFlag(FLAG_IS_EXPAND);
+ } else {
+ mTextView.setVisibility(GONE);
+ removeFlag(FLAG_IS_EXPAND);
+ }
+ mTextView.setHorizontallyScrolling(false);
+ mTextView.setEllipsize(TextUtils.TruncateAt.END);
+ }
+
+ @Override
+ public void onAnimationStart(Animator animator) {
+ mTextView.setHorizontallyScrolling(true);
+ mTextView.setVisibility(VISIBLE);
+ mTextView.setEllipsize(null);
+ }
+ });
+ animatorSet.playTogether(mPauseFABAnim, updatePauseTextAlpha(isExpanding));
+ animatorSet.start();
+ }
+
+
+ private ValueAnimator updatePauseTextAlpha(boolean expand) {
+ float from = expand ? 0 : 1;
+ float to = expand ? 1 : 0;
+ ValueAnimator alphaAnim = ObjectAnimator.ofFloat(from, to);
+ alphaAnim.setDuration(expand ? TEXT_EXPAND_OPACITY_DURATION
+ : TEXT_COLLAPSE_OPACITY_DURATION);
+ alphaAnim.setStartDelay(expand ? TEXT_ALPHA_EXPAND_DELAY : TEXT_ALPHA_COLLAPSE_DELAY);
+ alphaAnim.setInterpolator(Interpolators.LINEAR);
+ alphaAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator valueAnimator) {
+ mTextView.setAlpha((float) valueAnimator.getAnimatedValue());
+ }
+ });
+ return alphaAnim;
+ }
+
private void setInsets(Rect rect, Insets insets) {
rect.set(insets.left, insets.top, insets.right, insets.bottom);
}
@@ -166,7 +266,7 @@
@Override
public void onTranslationStart() {
- setFlag(FLAG_TRANSLATION_ONGOING);
+ addFlag(FLAG_TRANSLATION_ONGOING);
}
@Override
@@ -174,7 +274,7 @@
removeFlag(FLAG_TRANSLATION_ONGOING);
}
- private void setFlag(int flag) {
+ private void addFlag(int flag) {
mFlags |= flag;
}
@@ -182,12 +282,25 @@
mFlags &= ~flag;
}
+ private boolean containsFlag(int flag) {
+ return (mFlags & flag) == flag;
+ }
+
public void extend() {
- mTextView.setVisibility(VISIBLE);
+ animatePillTransition(true);
}
public void shrink(){
- mTextView.setVisibility(GONE);
+ animatePillTransition(false);
+ }
+
+ /**
+ * Determines if the button should animate based on current state. It should animate the button
+ * only if it is not in the same state it is animating to.
+ */
+ private boolean shouldAnimate(boolean expanding) {
+ return expanding != containsFlag(FLAG_IS_EXPAND)
+ && (mPauseFABAnim == null || !mPauseFABAnim.isRunning());
}
public int getScrollThreshold() {