Snap for 7929330 from 39aceb6dc7 to sc-v2-release
Change-Id: I1a9d23ddd153acd0e939b9730cb65d7594f4ba17
This commit is contained in:
@@ -204,6 +204,7 @@ android_library {
|
||||
],
|
||||
static_libs: [
|
||||
"Launcher3ResLib",
|
||||
"lottie",
|
||||
"SystemUISharedLib",
|
||||
"SystemUI-statsd",
|
||||
],
|
||||
|
||||
@@ -163,6 +163,8 @@ dependencies {
|
||||
androidTestImplementation 'com.android.support.test:rules:1.0.0'
|
||||
androidTestImplementation 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
|
||||
androidTestImplementation "androidx.annotation:annotation:${ANDROID_X_VERSION}"
|
||||
|
||||
api 'com.airbnb.android:lottie:3.3.0'
|
||||
}
|
||||
|
||||
protobuf {
|
||||
|
||||
@@ -25,82 +25,100 @@
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="@dimen/allset_page_margin_horizontal"
|
||||
android:layout_marginEnd="@dimen/allset_page_margin_horizontal"
|
||||
android:layoutDirection="locale"
|
||||
android:textDirection="locale"
|
||||
android:id="@+id/content_view"
|
||||
android:forceHasOverlappingRendering="false"
|
||||
android:fitsSystemWindows="true" >
|
||||
android:fitsSystemWindows="true">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/allset_title_icon_margin_top"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:src="@drawable/ic_all_set"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
style="@style/TextAppearance.GestureTutorial.Feedback.Title"
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/animated_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/allset_title_margin_top"
|
||||
app:layout_constraintTop_toBottomOf="@id/icon"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:gravity="start"
|
||||
android:text="@string/allset_title"/>
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:scaleType="centerCrop"
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subtitle"
|
||||
style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/allset_subtitle_margin_top"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintWidth_max="@dimen/allset_subtitle_width_max"
|
||||
android:gravity="start"
|
||||
android:text="@string/allset_description"/>
|
||||
app:lottie_rawRes="@raw/all_set_page_bg"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_loop="true" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/navigation_settings_guideline_bottom"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintGuide_percent="0.83" />
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="@dimen/allset_page_margin_horizontal"
|
||||
android:layout_marginEnd="@dimen/allset_page_margin_horizontal"
|
||||
android:layoutDirection="locale"
|
||||
android:textDirection="locale"
|
||||
android:forceHasOverlappingRendering="false"
|
||||
android:fitsSystemWindows="true" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/navigation_settings"
|
||||
style="@style/TextAppearance.GestureTutorial.LinkText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@id/navigation_settings_guideline_bottom"
|
||||
android:minHeight="48dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:text="@string/allset_navigation_settings" />
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/allset_title_icon_margin_top"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:src="@drawable/ic_all_set"/>
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/hint_guideline_bottom"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintGuide_percent="0.94" />
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
style="@style/TextAppearance.GestureTutorial.Feedback.Title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/allset_title_margin_top"
|
||||
app:layout_constraintTop_toBottomOf="@id/icon"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:gravity="start"
|
||||
android:text="@string/allset_title"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/subtitle"
|
||||
style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/allset_subtitle_margin_top"
|
||||
app:layout_constraintTop_toBottomOf="@id/title"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintWidth_max="@dimen/allset_subtitle_width_max"
|
||||
android:gravity="start"
|
||||
android:text="@string/allset_description"/>
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/navigation_settings_guideline_bottom"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintGuide_percent="0.83" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/navigation_settings"
|
||||
style="@style/TextAppearance.GestureTutorial.LinkText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@id/navigation_settings_guideline_bottom"
|
||||
android:minHeight="48dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:text="@string/allset_navigation_settings" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/hint_guideline_bottom"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintGuide_percent="0.94" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/hint"
|
||||
style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
|
||||
android:textSize="14sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@id/hint_guideline_bottom"
|
||||
android:text="@string/allset_hint"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/hint"
|
||||
style="@style/TextAppearance.GestureTutorial.Feedback.Subtitle"
|
||||
android:textSize="14sp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="@id/hint_guideline_bottom"
|
||||
android:text="@string/allset_hint"/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -28,6 +28,7 @@
|
||||
<dimen name="task_menu_item_corner_radius">4dp</dimen>
|
||||
<dimen name="task_menu_spacing">2dp</dimen>
|
||||
<dimen name="task_menu_width_grid">234dp</dimen>
|
||||
<dimen name="task_menu_horizontal_padding">8dp</dimen>
|
||||
<dimen name="overview_proactive_row_height">48dp</dimen>
|
||||
<dimen name="overview_proactive_row_bottom_margin">16dp</dimen>
|
||||
|
||||
|
||||
@@ -143,8 +143,7 @@ public class TaskbarDragLayerController {
|
||||
// Let touches pass through us.
|
||||
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
|
||||
} else if (mControllers.navbarButtonsViewController.isImeVisible()) {
|
||||
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_CONTENT);
|
||||
insetsIsTouchableRegion = false;
|
||||
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
|
||||
} else if (!mControllers.uiController.isTaskbarTouchable()) {
|
||||
// Let touches pass through us.
|
||||
insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION);
|
||||
|
||||
@@ -30,6 +30,7 @@ public class KtR {
|
||||
|
||||
public static final class dimen {
|
||||
public static int task_menu_spacing = R.dimen.task_menu_spacing;
|
||||
public static int task_menu_horizontal_padding = R.dimen.task_menu_horizontal_padding;
|
||||
}
|
||||
|
||||
public static final class layout {
|
||||
|
||||
@@ -208,13 +208,6 @@ public class TaskOverlayFactory implements ResourceBasedOverride {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the current task's thumbnail has changed.
|
||||
*/
|
||||
public void refreshActionVisibility(ThumbnailData thumbnail) {
|
||||
getActionsView().updateDisabledFlags(DISABLED_NO_THUMBNAIL, thumbnail == null);
|
||||
}
|
||||
|
||||
/**
|
||||
* End rendering live tile in Overview.
|
||||
*
|
||||
|
||||
@@ -134,7 +134,8 @@ public class TaskThumbnailCache {
|
||||
Preconditions.assertUIThread();
|
||||
|
||||
boolean lowResolution = !mHighResLoadingState.isEnabled();
|
||||
if (task.thumbnail != null && (!task.thumbnail.reducedResolution || lowResolution)) {
|
||||
if (task.thumbnail != null && task.thumbnail.thumbnail != null
|
||||
&& (!task.thumbnail.reducedResolution || lowResolution)) {
|
||||
// Nothing to load, the thumbnail is already high-resolution or matches what the
|
||||
// request, so just callback
|
||||
callback.accept(task.thumbnail);
|
||||
@@ -152,7 +153,8 @@ public class TaskThumbnailCache {
|
||||
Preconditions.assertUIThread();
|
||||
|
||||
ThumbnailData cachedThumbnail = mCache.getAndInvalidateIfModified(key);
|
||||
if (cachedThumbnail != null && (!cachedThumbnail.reducedResolution || lowResolution)) {
|
||||
if (cachedThumbnail != null && cachedThumbnail.thumbnail != null
|
||||
&& (!cachedThumbnail.reducedResolution || lowResolution)) {
|
||||
// Already cached, lets use that thumbnail
|
||||
callback.accept(cachedThumbnail);
|
||||
return null;
|
||||
|
||||
@@ -32,7 +32,6 @@ import static com.android.launcher3.QuickstepTransitionManager.SPLIT_LAUNCH_DURA
|
||||
import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
|
||||
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR_ACCEL_DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.clampToProgress;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
|
||||
import static com.android.launcher3.statehandlers.DepthController.DEPTH;
|
||||
@@ -193,7 +192,6 @@ public final class TaskViewUtils {
|
||||
boolean showAsGrid = dp.overviewShowAsGrid;
|
||||
boolean parallaxCenterAndAdjacentTask =
|
||||
taskIndex != recentsView.getCurrentPage() && !showAsGrid;
|
||||
float gridTranslationSecondary = recentsView.getGridTranslationSecondary(taskIndex);
|
||||
int startScroll = recentsView.getScrollOffset(taskIndex);
|
||||
|
||||
RemoteTargetHandle[] topMostSimulators = null;
|
||||
@@ -211,11 +209,9 @@ public final class TaskViewUtils {
|
||||
|
||||
tvsLocal.fullScreenProgress.value = 0;
|
||||
tvsLocal.recentsViewScale.value = 1;
|
||||
if (showAsGrid) {
|
||||
tvsLocal.taskSecondaryTranslation.value = gridTranslationSecondary;
|
||||
}
|
||||
tvsLocal.setScroll(startScroll);
|
||||
tvsLocal.setIsGridTask(v.isGridTask());
|
||||
tvsLocal.setGridTranslationY(v.getGridTranslationY());
|
||||
|
||||
// Fade in the task during the initial 20% of the animation
|
||||
out.addFloat(targetHandle.getTransformParams(), TransformParams.TARGET_ALPHA, 0, 1,
|
||||
@@ -230,10 +226,6 @@ public final class TaskViewUtils {
|
||||
out.setFloat(tvsLocal.recentsViewScale,
|
||||
AnimatedFloat.VALUE, tvsLocal.getFullScreenScale(),
|
||||
TOUCH_RESPONSE_INTERPOLATOR);
|
||||
if (showAsGrid) {
|
||||
out.setFloat(tvsLocal.taskSecondaryTranslation, AnimatedFloat.VALUE, 0,
|
||||
TOUCH_RESPONSE_INTERPOLATOR_ACCEL_DEACCEL);
|
||||
}
|
||||
out.setFloat(tvsLocal.recentsViewScroll, AnimatedFloat.VALUE, 0,
|
||||
TOUCH_RESPONSE_INTERPOLATOR);
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.android.quickstep.fallback;
|
||||
|
||||
import static com.android.quickstep.GestureState.GestureEndTarget.RECENTS;
|
||||
import static com.android.quickstep.ViewUtils.postFrameDrawn;
|
||||
import static com.android.quickstep.fallback.RecentsState.DEFAULT;
|
||||
import static com.android.quickstep.fallback.RecentsState.HOME;
|
||||
import static com.android.quickstep.fallback.RecentsState.MODAL_TASK;
|
||||
@@ -218,8 +219,14 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||
|
||||
@Override
|
||||
public void onStateTransitionComplete(RecentsState finalState) {
|
||||
setOverlayEnabled(finalState == DEFAULT || finalState == MODAL_TASK);
|
||||
boolean isOverlayEnabled = finalState == DEFAULT || finalState == MODAL_TASK;
|
||||
setOverlayEnabled(isOverlayEnabled);
|
||||
setFreezeViewVisibility(false);
|
||||
|
||||
if (isOverlayEnabled) {
|
||||
postFrameDrawn(this, () -> runActionOnRemoteHandles(remoteTargetHandle ->
|
||||
remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(true)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@ import static com.android.launcher3.Utilities.mapBoundToRange;
|
||||
import static com.android.launcher3.Utilities.mapRange;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager.RunningTaskInfo;
|
||||
import android.content.Context;
|
||||
@@ -38,6 +39,8 @@ import android.graphics.Rect;
|
||||
import android.graphics.Shader.TileMode;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.View.AccessibilityDelegate;
|
||||
@@ -56,6 +59,8 @@ import com.android.quickstep.GestureState;
|
||||
import com.android.quickstep.TouchInteractionService.TISBinder;
|
||||
import com.android.quickstep.util.TISBindHelper;
|
||||
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
/**
|
||||
@@ -80,6 +85,10 @@ public class AllSetActivity extends Activity {
|
||||
private View mContentView;
|
||||
private float mSwipeUpShift;
|
||||
|
||||
@Nullable private Vibrator mVibrator;
|
||||
private LottieAnimationView mAnimatedBackground;
|
||||
private Animator.AnimatorListener mBackgroundAnimatorListener;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -115,6 +124,52 @@ public class AllSetActivity extends Activity {
|
||||
|
||||
findViewById(R.id.hint).setAccessibilityDelegate(new SkipButtonAccessibilityDelegate());
|
||||
mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
|
||||
|
||||
mVibrator = getSystemService(Vibrator.class);
|
||||
mAnimatedBackground = findViewById(R.id.animated_background);
|
||||
startBackgroundAnimation();
|
||||
}
|
||||
|
||||
private void startBackgroundAnimation() {
|
||||
if (Utilities.ATLEAST_S && mVibrator != null && mVibrator.areAllPrimitivesSupported(
|
||||
VibrationEffect.Composition.PRIMITIVE_THUD)) {
|
||||
if (mBackgroundAnimatorListener == null) {
|
||||
mBackgroundAnimatorListener =
|
||||
new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
mVibrator.vibrate(getVibrationEffect());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
mVibrator.vibrate(getVibrationEffect());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mVibrator.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
mVibrator.cancel();
|
||||
}
|
||||
};
|
||||
}
|
||||
mAnimatedBackground.addAnimatorListener(mBackgroundAnimatorListener);
|
||||
}
|
||||
mAnimatedBackground.playAnimation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the vibration effect for the next round of animation. The parameters vary between
|
||||
* different illustrations.
|
||||
*/
|
||||
private VibrationEffect getVibrationEffect() {
|
||||
return VibrationEffect.startComposition()
|
||||
.addPrimitive(VibrationEffect.Composition.PRIMITIVE_THUD, 1.0f, 50)
|
||||
.compose();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,6 +208,9 @@ public class AllSetActivity extends Activity {
|
||||
super.onDestroy();
|
||||
mTISBindHelper.onDestroy();
|
||||
clearBinderOverride();
|
||||
if (mBackgroundAnimatorListener != null) {
|
||||
mAnimatedBackground.removeAnimatorListener(mBackgroundAnimatorListener);
|
||||
}
|
||||
}
|
||||
|
||||
private AnimatedFloat createSwipeUpProxy(GestureState state) {
|
||||
@@ -173,6 +231,12 @@ public class AllSetActivity extends Activity {
|
||||
1, 0, LINEAR);
|
||||
mContentView.setAlpha(alpha);
|
||||
mContentView.setTranslationY((alpha - 1) * mSwipeUpShift);
|
||||
|
||||
if (alpha == 0f) {
|
||||
mAnimatedBackground.pauseAnimation();
|
||||
} else if (!mAnimatedBackground.isAnimating()) {
|
||||
mAnimatedBackground.resumeAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -102,6 +102,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
private StagedSplitBounds mStagedSplitBounds;
|
||||
private boolean mDrawsBelowRecents;
|
||||
private boolean mIsGridTask;
|
||||
private float mGridTranslationY;
|
||||
|
||||
public TaskViewSimulator(Context context, BaseActivityInterface sizeStrategy) {
|
||||
mContext = context;
|
||||
@@ -156,9 +157,15 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
fullTaskSize = new Rect(mTaskRect);
|
||||
mOrientationState.getOrientationHandler()
|
||||
.setSplitTaskSwipeRect(mDp, mTaskRect, mStagedSplitBounds, mStagePosition);
|
||||
if (mIsGridTask) {
|
||||
mTaskRect.offset(0, (int) mGridTranslationY);
|
||||
}
|
||||
} else {
|
||||
fullTaskSize = mTaskRect;
|
||||
}
|
||||
if (mIsGridTask) {
|
||||
fullTaskSize.offset(0, (int) mGridTranslationY);
|
||||
}
|
||||
return mOrientationState.getFullScreenScaleAndPivot(fullTaskSize, mDp, mPivot);
|
||||
}
|
||||
|
||||
@@ -217,6 +224,13 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
mIsGridTask = isGridTask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the y-translation when overview is in grid.
|
||||
*/
|
||||
public void setGridTranslationY(float gridTranslationY) {
|
||||
mGridTranslationY = gridTranslationY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds animation for all the components corresponding to transition from an app to overview.
|
||||
*/
|
||||
@@ -320,14 +334,12 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
mMatrix.postTranslate(insets.left, insets.top);
|
||||
mMatrix.postScale(scale, scale);
|
||||
|
||||
// Apply TaskView matrix: translate, scroll
|
||||
// Apply TaskView matrix: taskRect, translate
|
||||
mMatrix.postTranslate(mTaskRect.left, mTaskRect.top);
|
||||
mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
|
||||
taskPrimaryTranslation.value);
|
||||
mOrientationState.getOrientationHandler().setSecondary(mMatrix, MATRIX_POST_TRANSLATE,
|
||||
taskSecondaryTranslation.value);
|
||||
mOrientationState.getOrientationHandler().set(
|
||||
mMatrix, MATRIX_POST_TRANSLATE, recentsViewScroll.value);
|
||||
|
||||
// Apply RecentsView matrix
|
||||
mMatrix.postScale(recentsViewScale.value, recentsViewScale.value, mPivot.x, mPivot.y);
|
||||
@@ -335,6 +347,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||
recentsViewSecondaryTranslation.value);
|
||||
mOrientationState.getOrientationHandler().set(mMatrix, MATRIX_POST_TRANSLATE,
|
||||
recentsViewPrimaryTranslation.value);
|
||||
mOrientationState.getOrientationHandler().set(
|
||||
mMatrix, MATRIX_POST_TRANSLATE, recentsViewScroll.value);
|
||||
applyWindowToHomeRotation(mMatrix);
|
||||
|
||||
// Crop rect is the inverse of thumbnail matrix
|
||||
|
||||
@@ -4,7 +4,6 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITIO
|
||||
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
@@ -50,8 +49,6 @@ public class GroupedTaskView extends TaskView {
|
||||
private final float[] mIcon2CenterCoords = new float[2];
|
||||
private TransformingTouchDelegate mIcon2TouchDelegate;
|
||||
@Nullable private StagedSplitBounds mSplitBoundsConfig;
|
||||
private final Rect mPrimaryTempRect = new Rect();
|
||||
private final Rect mSecondaryTempRect = new Rect();
|
||||
|
||||
public GroupedTaskView(Context context) {
|
||||
super(context);
|
||||
@@ -239,10 +236,8 @@ public class GroupedTaskView extends TaskView {
|
||||
int taskIconHeight = deviceProfile.overviewTaskIconSizePx;
|
||||
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
|
||||
|
||||
mSnapshotView.getBoundsOnScreen(mPrimaryTempRect);
|
||||
mSnapshotView2.getBoundsOnScreen(mSecondaryTempRect);
|
||||
getPagedOrientationHandler().setSplitIconParams(mIconView, mIconView2,
|
||||
taskIconHeight, mPrimaryTempRect, mSecondaryTempRect,
|
||||
taskIconHeight, mSnapshotView.getWidth(), mSnapshotView.getHeight(),
|
||||
isRtl, deviceProfile, mSplitBoundsConfig);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
|
||||
import static com.android.launcher3.LauncherState.SPRING_LOADED;
|
||||
import static com.android.quickstep.ViewUtils.postFrameDrawn;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
@@ -104,8 +105,14 @@ public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher, Laun
|
||||
|
||||
@Override
|
||||
public void onStateTransitionComplete(LauncherState finalState) {
|
||||
setOverlayEnabled(finalState == OVERVIEW || finalState == OVERVIEW_MODAL_TASK);
|
||||
boolean isOverlayEnabled = finalState == OVERVIEW || finalState == OVERVIEW_MODAL_TASK;
|
||||
setOverlayEnabled(isOverlayEnabled);
|
||||
setFreezeViewVisibility(false);
|
||||
|
||||
if (isOverlayEnabled) {
|
||||
postFrameDrawn(this, () -> runActionOnRemoteHandles(remoteTargetHandle ->
|
||||
remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(true)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1508,17 +1508,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
}
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
// Since we reuse the same mLiveTileTaskViewSimulator in the RecentsView, we need
|
||||
// to reset the params after it settles in Overview from swipe up so that we don't
|
||||
// render with obsolete param values.
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> {
|
||||
TaskViewSimulator simulator = remoteTargetHandle.getTaskViewSimulator();
|
||||
simulator.taskPrimaryTranslation.value = 0;
|
||||
simulator.taskSecondaryTranslation.value = 0;
|
||||
simulator.fullScreenProgress.value = 0;
|
||||
simulator.recentsViewScale.value = 1;
|
||||
});
|
||||
|
||||
// Similar to setRunningTaskHidden below, reapply the state before runningTaskView is
|
||||
// null.
|
||||
if (!mRunningTaskShowScreenshot) {
|
||||
@@ -1906,7 +1895,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
setEnableDrawingLiveTile(false);
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> {
|
||||
remoteTargetHandle.getTransformParams().setTargetSet(null);
|
||||
remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(true);
|
||||
remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(false);
|
||||
});
|
||||
mSplitSelectStateController.resetState();
|
||||
|
||||
@@ -4389,7 +4378,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
TaskViewSimulator tvs = remoteTargetHandle.getTaskViewSimulator();
|
||||
tvs.setOrientationState(mOrientationState);
|
||||
tvs.setDp(mActivity.getDeviceProfile());
|
||||
tvs.setDrawsBelowRecents(true);
|
||||
tvs.recentsViewScale.value = 1;
|
||||
}
|
||||
}
|
||||
@@ -4691,20 +4679,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
return position != -1 ? position : bottomRowIdArray.indexOf(taskView.getTaskViewId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns how many pixels the task is offset on the currently laid out secondary axis
|
||||
* according to {@link #mGridProgress}.
|
||||
*/
|
||||
public float getGridTranslationSecondary(int pageIndex) {
|
||||
TaskView taskView = getTaskViewAt(pageIndex);
|
||||
if (taskView == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return mOrientationHandler.getSecondaryValue(taskView.getGridTranslationX(),
|
||||
taskView.getGridTranslationY());
|
||||
}
|
||||
|
||||
public Consumer<MotionEvent> getEventDispatcher(float navbarRotation) {
|
||||
float degreesRotated;
|
||||
if (navbarRotation == 0) {
|
||||
|
||||
@@ -23,14 +23,18 @@ import android.graphics.Rect
|
||||
import android.graphics.drawable.ShapeDrawable
|
||||
import android.graphics.drawable.shapes.RectShape
|
||||
import android.util.AttributeSet
|
||||
import android.view.Gravity
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.LinearLayout
|
||||
import com.android.launcher3.BaseDraggingActivity
|
||||
import com.android.launcher3.DeviceProfile
|
||||
import com.android.launcher3.InsettableFrameLayout
|
||||
import com.android.launcher3.R
|
||||
import com.android.launcher3.popup.ArrowPopup
|
||||
import com.android.launcher3.popup.RoundedArrowDrawable
|
||||
import com.android.launcher3.popup.SystemShortcut
|
||||
import com.android.launcher3.util.Themes
|
||||
import com.android.quickstep.KtR
|
||||
@@ -43,9 +47,13 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
|
||||
|
||||
fun showForTask(taskContainer: TaskIdAttributeContainer): Boolean {
|
||||
val activity = BaseDraggingActivity
|
||||
.fromContext<BaseDraggingActivity>(taskContainer.taskView.context)
|
||||
.fromContext<BaseDraggingActivity>(taskContainer.taskView.context)
|
||||
val taskMenuViewWithArrow = activity.layoutInflater
|
||||
.inflate(KtR.layout.task_menu_with_arrow, activity.dragLayer, false) as TaskMenuViewWithArrow<*>
|
||||
.inflate(
|
||||
KtR.layout.task_menu_with_arrow,
|
||||
activity.dragLayer,
|
||||
false
|
||||
) as TaskMenuViewWithArrow<*>
|
||||
|
||||
return taskMenuViewWithArrow.populateAndShowForTask(taskContainer)
|
||||
}
|
||||
@@ -53,10 +61,21 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
|
||||
context,
|
||||
attrs,
|
||||
defStyleAttr
|
||||
)
|
||||
|
||||
init {
|
||||
clipToOutline = true
|
||||
|
||||
shouldScaleArrow = true
|
||||
// This synchronizes the arrow and menu to open at the same time
|
||||
OPEN_CHILD_FADE_START_DELAY = OPEN_FADE_START_DELAY
|
||||
OPEN_CHILD_FADE_DURATION = OPEN_FADE_DURATION
|
||||
CLOSE_FADE_START_DELAY = CLOSE_CHILD_FADE_START_DELAY
|
||||
CLOSE_FADE_DURATION = CLOSE_CHILD_FADE_DURATION
|
||||
}
|
||||
|
||||
private val menuWidth = context.resources.getDimensionPixelSize(R.dimen.task_menu_width_grid)
|
||||
@@ -65,6 +84,13 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
|
||||
private lateinit var optionLayout: LinearLayout
|
||||
private lateinit var taskContainer: TaskIdAttributeContainer
|
||||
|
||||
private var optionMeasuredHeight = 0
|
||||
private val arrowHorizontalPadding: Int
|
||||
get() = if (taskView.isFocusedTask)
|
||||
resources.getDimensionPixelSize(KtR.dimen.task_menu_horizontal_padding)
|
||||
else
|
||||
0
|
||||
|
||||
override fun isOfType(type: Int): Boolean = type and TYPE_TASK_MENU != 0
|
||||
|
||||
override fun getTargetObjectLocation(outPos: Rect?) {
|
||||
@@ -147,7 +173,10 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
|
||||
}
|
||||
|
||||
override fun assignMarginsAndBackgrounds(viewGroup: ViewGroup) {
|
||||
assignMarginsAndBackgrounds(this, Themes.getAttrColor(context, com.android.internal.R.attr.colorSurface))
|
||||
assignMarginsAndBackgrounds(
|
||||
this,
|
||||
Themes.getAttrColor(context, com.android.internal.R.attr.colorSurface)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onCreateOpenAnimation(anim: AnimatorSet) {
|
||||
@@ -164,4 +193,90 @@ class TaskMenuViewWithArrow<T : BaseDraggingActivity> : ArrowPopup<T> {
|
||||
ObjectAnimator.ofFloat(taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA, 0f)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Orients this container to the left or right of the given icon, aligning with the first option
|
||||
* or second.
|
||||
*
|
||||
* These are the preferred orientations, in order (RTL prefers right-aligned over left):
|
||||
* - Right and first option aligned
|
||||
* - Right and second option aligned
|
||||
* - Left and first option aligned
|
||||
* - Left and second option aligned
|
||||
*
|
||||
* So we always align right if there is enough horizontal space
|
||||
*/
|
||||
override fun orientAboutObject() {
|
||||
measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
|
||||
// Needed for offsets later
|
||||
optionMeasuredHeight = optionLayout.getChildAt(0).measuredHeight
|
||||
val extraHorizontalSpace = (mArrowHeight + mArrowOffsetVertical + arrowHorizontalPadding)
|
||||
|
||||
val widthWithArrow = measuredWidth + paddingLeft + paddingRight + extraHorizontalSpace
|
||||
getTargetObjectLocation(mTempRect)
|
||||
val dragLayer: InsettableFrameLayout = popupContainer
|
||||
val insets = dragLayer.insets
|
||||
|
||||
// Put to the right of the icon if there is space, which means left aligned with the menu
|
||||
val rightAlignedMenuStartX = mTempRect.left - widthWithArrow
|
||||
val leftAlignedMenuStartX = mTempRect.right + extraHorizontalSpace
|
||||
mIsLeftAligned = if (mIsRtl) {
|
||||
rightAlignedMenuStartX + insets.left < 0
|
||||
} else {
|
||||
leftAlignedMenuStartX + (widthWithArrow - extraHorizontalSpace) + insets.left <
|
||||
dragLayer.width - insets.right
|
||||
}
|
||||
|
||||
var menuStartX = if (mIsLeftAligned) leftAlignedMenuStartX else rightAlignedMenuStartX
|
||||
|
||||
// Offset y so that the arrow and first row are center-aligned with the original icon.
|
||||
val iconHeight = mTempRect.height()
|
||||
val optionHeight = optionMeasuredHeight
|
||||
val yOffset = (optionHeight - iconHeight) / 2
|
||||
var menuStartY = mTempRect.top - yOffset
|
||||
|
||||
// Insets are added later, so subtract them now.
|
||||
menuStartX -= insets.left
|
||||
menuStartY -= insets.top
|
||||
|
||||
setX(menuStartX.toFloat())
|
||||
setY(menuStartY.toFloat())
|
||||
|
||||
val lp = layoutParams as FrameLayout.LayoutParams
|
||||
val arrowLp = mArrow.layoutParams as FrameLayout.LayoutParams
|
||||
lp.gravity = Gravity.TOP
|
||||
arrowLp.gravity = lp.gravity
|
||||
}
|
||||
|
||||
override fun addArrow() {
|
||||
popupContainer.addView(mArrow)
|
||||
mArrow.x = getArrowX()
|
||||
mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2)
|
||||
|
||||
updateArrowColor()
|
||||
|
||||
// This is inverted (x = height, y = width) because the arrow is rotated
|
||||
mArrow.pivotX = if (mIsLeftAligned) 0f else mArrowHeight.toFloat()
|
||||
mArrow.pivotY = 0f
|
||||
}
|
||||
|
||||
private fun getArrowX(): Float {
|
||||
return if (mIsLeftAligned)
|
||||
x - mArrowHeight
|
||||
else
|
||||
x + measuredWidth + mArrowOffsetVertical
|
||||
}
|
||||
|
||||
override fun updateArrowColor() {
|
||||
mArrow.background = RoundedArrowDrawable(
|
||||
mArrowWidth.toFloat(),
|
||||
mArrowHeight.toFloat(),
|
||||
mArrowPointRadius.toFloat(),
|
||||
mIsLeftAligned,
|
||||
mArrowColor
|
||||
)
|
||||
elevation = mElevation
|
||||
mArrow.elevation = mElevation
|
||||
}
|
||||
|
||||
}
|
||||
@@ -148,10 +148,11 @@ public class TaskThumbnailView extends View {
|
||||
public void setThumbnail(@Nullable Task task, @Nullable ThumbnailData thumbnailData,
|
||||
boolean refreshNow) {
|
||||
mTask = task;
|
||||
boolean thumbnailWasNull = mThumbnailData == null;
|
||||
mThumbnailData =
|
||||
(thumbnailData != null && thumbnailData.thumbnail != null) ? thumbnailData : null;
|
||||
if (refreshNow) {
|
||||
refresh();
|
||||
refresh(thumbnailWasNull && mThumbnailData != null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,14 +163,22 @@ public class TaskThumbnailView extends View {
|
||||
|
||||
/** Updates the shader, paint, matrix to redraw. */
|
||||
public void refresh() {
|
||||
refresh(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the shader, paint, matrix to redraw.
|
||||
* @param shouldRefreshOverlay whether to re-initialize overlay
|
||||
*/
|
||||
private void refresh(boolean shouldRefreshOverlay) {
|
||||
if (mThumbnailData != null && mThumbnailData.thumbnail != null) {
|
||||
Bitmap bm = mThumbnailData.thumbnail;
|
||||
bm.prepareToDraw();
|
||||
mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
|
||||
mPaint.setShader(mBitmapShader);
|
||||
updateThumbnailMatrix();
|
||||
if (mOverlayEnabled) {
|
||||
getTaskOverlay().refreshActionVisibility(mThumbnailData);
|
||||
if (shouldRefreshOverlay) {
|
||||
refreshOverlay();
|
||||
}
|
||||
} else {
|
||||
mBitmapShader = null;
|
||||
|
||||
@@ -648,7 +648,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
recentsView.getDepthController());
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animator) {
|
||||
public void onAnimationStart(Animator animation) {
|
||||
recentsView.runActionOnRemoteHandles(
|
||||
(Consumer<RemoteTargetHandle>) remoteTargetHandle ->
|
||||
remoteTargetHandle
|
||||
@@ -658,11 +658,6 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
recentsView.runActionOnRemoteHandles(
|
||||
(Consumer<RemoteTargetHandle>) remoteTargetHandle ->
|
||||
remoteTargetHandle
|
||||
.getTaskViewSimulator()
|
||||
.setDrawsBelowRecents(true));
|
||||
mIsClickableAsLiveTile = true;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -33,6 +33,14 @@
|
||||
android:layout_height="match_parent"
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_gravity="fill"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/widget_badge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:importantForAccessibility="no"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:layout_margin="@dimen/profile_badge_margin"/>
|
||||
</com.android.launcher3.widget.WidgetCellPreview>
|
||||
|
||||
<!-- The name of the widget. -->
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -36,8 +36,8 @@
|
||||
<string name="add_item_request_drag_hint" msgid="5653291305078645405">"Tocca e tieni premuto il widget per spostarlo nella schermata Home"</string>
|
||||
<string name="add_to_home_screen" msgid="8631549138215492708">"Aggiungi a schermata Home"</string>
|
||||
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> aggiunto alla schermata Home"</string>
|
||||
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widget}}"</string>
|
||||
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# scorciatoia}other{# scorciatoie}}"</string>
|
||||
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# widget}}"</string>
|
||||
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# scorciatoia}one{# scorciatoia}other{# scorciatoie}}"</string>
|
||||
<string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
|
||||
<string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
|
||||
<string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Cerca"</string>
|
||||
@@ -86,7 +86,7 @@
|
||||
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Questa è un\'app di sistema e non può essere disinstallata."</string>
|
||||
<string name="folder_hint_text" msgid="5174843001373488816">"Modifica nome"</string>
|
||||
<string name="disabled_app_label" msgid="6673129024321402780">"App <xliff:g id="APP_NAME">%1$s</xliff:g> disattivata"</string>
|
||||
<string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ha # notifica}other{{app_name} ha # notifiche}}"</string>
|
||||
<string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ha # notifica}one{{app_name} ha # notifica}other{{app_name} ha # notifiche}}"</string>
|
||||
<string name="default_scroll_format" msgid="7475544710230993317">"Pagina %1$d di %2$d"</string>
|
||||
<string name="workspace_scroll_format" msgid="8458889198184077399">"Schermata Home %1$d di %2$d"</string>
|
||||
<string name="workspace_new_page" msgid="257366611030256142">"Nuova pagina Schermata Home"</string>
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
<string name="add_item_request_drag_hint" msgid="5653291305078645405">"Toque sem soltar no widget para o mover à volta do ecrã principal"</string>
|
||||
<string name="add_to_home_screen" msgid="8631549138215492708">"Adicionar ao ecrã principal"</string>
|
||||
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> adicionado ao ecrã principal"</string>
|
||||
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
|
||||
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# atalho}other{# atalhos}}"</string>
|
||||
<string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget(s)}other{# widgets}}"</string>
|
||||
<string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# atalho}one{# atalho(s)}other{# atalhos}}"</string>
|
||||
<string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
|
||||
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
|
||||
<string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Pesquisar"</string>
|
||||
@@ -86,7 +86,7 @@
|
||||
<string name="uninstall_system_app_text" msgid="4172046090762920660">"É uma app de sistema e não pode ser desinstalada."</string>
|
||||
<string name="folder_hint_text" msgid="5174843001373488816">"Edite o nome"</string>
|
||||
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> desativado"</string>
|
||||
<string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{A app {app_name} tem # notificação}other{A app {app_name} tem # notificações}}"</string>
|
||||
<string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{A app {app_name} tem # notificação}one{A app {app_name} tem # notificação(ões)}other{A app {app_name} tem # notificações}}"</string>
|
||||
<string name="default_scroll_format" msgid="7475544710230993317">"Página %1$d de %2$d"</string>
|
||||
<string name="workspace_scroll_format" msgid="8458889198184077399">"Ecrã principal %1$d de %2$d"</string>
|
||||
<string name="workspace_new_page" msgid="257366611030256142">"Nova página do ecrã principal"</string>
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.android.launcher3;
|
||||
import static android.animation.ValueAnimator.areAnimatorsEnabled;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5;
|
||||
import static com.android.launcher3.dragndrop.DraggableView.DRAGGABLE_ICON;
|
||||
import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
@@ -37,7 +39,6 @@ import android.graphics.Point;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Parcelable;
|
||||
import android.util.ArrayMap;
|
||||
@@ -61,6 +62,7 @@ import com.android.launcher3.LauncherSettings.Favorites;
|
||||
import com.android.launcher3.accessibility.DragAndDropAccessibilityDelegate;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.dragndrop.DraggableView;
|
||||
import com.android.launcher3.folder.PreviewBackground;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.util.CellAndSpan;
|
||||
@@ -442,18 +444,43 @@ public class CellLayout extends ViewGroup {
|
||||
}
|
||||
|
||||
if (DEBUG_VISUALIZE_OCCUPIED) {
|
||||
int[] pt = new int[2];
|
||||
ColorDrawable cd = new ColorDrawable(Color.RED);
|
||||
cd.setBounds(0, 0, mCellWidth, mCellHeight);
|
||||
for (int i = 0; i < mCountX; i++) {
|
||||
for (int j = 0; j < mCountY; j++) {
|
||||
if (mOccupied.cells[i][j]) {
|
||||
cellToPoint(i, j, pt);
|
||||
canvas.save();
|
||||
canvas.translate(pt[0], pt[1]);
|
||||
cd.draw(canvas);
|
||||
canvas.restore();
|
||||
Rect cellBounds = new Rect();
|
||||
// Will contain the bounds of the cell including spacing between cells.
|
||||
Rect cellBoundsWithSpacing = new Rect();
|
||||
int[] targetCell = new int[2];
|
||||
int[] cellCenter = new int[2];
|
||||
Paint debugPaint = new Paint();
|
||||
debugPaint.setStrokeWidth(Utilities.dpToPx(1));
|
||||
for (int x = 0; x < mCountX; x++) {
|
||||
for (int y = 0; y < mCountY; y++) {
|
||||
if (!mOccupied.cells[x][y]) {
|
||||
continue;
|
||||
}
|
||||
targetCell[0] = x;
|
||||
targetCell[1] = y;
|
||||
|
||||
boolean canCreateFolder = canCreateFolder(getChildAt(x, y));
|
||||
cellToRect(x, y, 1, 1, cellBounds);
|
||||
cellBoundsWithSpacing.set(cellBounds);
|
||||
cellBoundsWithSpacing.inset(-mBorderSpace.x / 2, -mBorderSpace.y / 2);
|
||||
getWorkspaceCellVisualCenter(x, y, cellCenter);
|
||||
|
||||
canvas.save();
|
||||
canvas.clipRect(cellBoundsWithSpacing);
|
||||
|
||||
// Draw reorder drag target.
|
||||
debugPaint.setColor(Color.RED);
|
||||
canvas.drawCircle(cellCenter[0], cellCenter[1], getReorderRadius(targetCell),
|
||||
debugPaint);
|
||||
|
||||
// Draw folder creation drag target.
|
||||
if (canCreateFolder) {
|
||||
debugPaint.setColor(Color.GREEN);
|
||||
canvas.drawCircle(cellCenter[0], cellCenter[1],
|
||||
getFolderCreationRadius(targetCell), debugPaint);
|
||||
}
|
||||
|
||||
canvas.restore();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -481,6 +508,14 @@ public class CellLayout extends ViewGroup {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether dropping an icon on the given View can create (or add to) a folder.
|
||||
*/
|
||||
private boolean canCreateFolder(View child) {
|
||||
return child instanceof DraggableView
|
||||
&& ((DraggableView) child).getViewType() == DRAGGABLE_ICON;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates the progress of the Workspace entering the SpringLoaded state; allows the
|
||||
* CellLayout to update various visuals for this state.
|
||||
@@ -817,7 +852,7 @@ public class CellLayout extends ViewGroup {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a cell coordinate and span return the point that represents the center of the regio
|
||||
* Given a cell coordinate and span return the point that represents the center of the region
|
||||
*
|
||||
* @param cellX X coordinate of the cell
|
||||
* @param cellY Y coordinate of the cell
|
||||
@@ -830,11 +865,65 @@ public class CellLayout extends ViewGroup {
|
||||
result[1] = mTempRect.centerY();
|
||||
}
|
||||
|
||||
public float getDistanceFromCell(float x, float y, int[] cell) {
|
||||
cellToCenterPoint(cell[0], cell[1], mTmpPoint);
|
||||
/**
|
||||
* Returns the distance between the given coordinate and the visual center of the given cell.
|
||||
*/
|
||||
public float getDistanceFromWorkspaceCellVisualCenter(float x, float y, int[] cell) {
|
||||
getWorkspaceCellVisualCenter(cell[0], cell[1], mTmpPoint);
|
||||
return (float) Math.hypot(x - mTmpPoint[0], y - mTmpPoint[1]);
|
||||
}
|
||||
|
||||
private void getWorkspaceCellVisualCenter(int cellX, int cellY, int[] outPoint) {
|
||||
View child = getChildAt(cellX, cellY);
|
||||
if (child instanceof DraggableView) {
|
||||
DraggableView draggableChild = (DraggableView) child;
|
||||
if (draggableChild.getViewType() == DRAGGABLE_ICON) {
|
||||
cellToPoint(cellX, cellY, outPoint);
|
||||
draggableChild.getWorkspaceVisualDragBounds(mTempRect);
|
||||
mTempRect.offset(outPoint[0], outPoint[1]);
|
||||
outPoint[0] = mTempRect.centerX();
|
||||
outPoint[1] = mTempRect.centerY();
|
||||
return;
|
||||
}
|
||||
}
|
||||
cellToCenterPoint(cellX, cellY, outPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the max distance from the center of a cell that can accept a drop to create a folder.
|
||||
*/
|
||||
public float getFolderCreationRadius(int[] targetCell) {
|
||||
DeviceProfile grid = mActivity.getDeviceProfile();
|
||||
float iconVisibleRadius = ICON_VISIBLE_AREA_FACTOR * grid.iconSizePx / 2;
|
||||
// Halfway between reorder radius and icon.
|
||||
return (getReorderRadius(targetCell) + iconVisibleRadius) / 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the max distance from the center of a cell that will start to reorder on drag over.
|
||||
*/
|
||||
public float getReorderRadius(int[] targetCell) {
|
||||
int[] centerPoint = mTmpPoint;
|
||||
getWorkspaceCellVisualCenter(targetCell[0], targetCell[1], centerPoint);
|
||||
|
||||
Rect cellBoundsWithSpacing = mTempRect;
|
||||
cellToRect(targetCell[0], targetCell[1], 1, 1, cellBoundsWithSpacing);
|
||||
cellBoundsWithSpacing.inset(-mBorderSpace.x / 2, -mBorderSpace.y / 2);
|
||||
|
||||
if (canCreateFolder(getChildAt(targetCell[0], targetCell[1]))) {
|
||||
// Take only the circle in the smaller dimension, to ensure we don't start reordering
|
||||
// too soon before accepting a folder drop.
|
||||
int minRadius = centerPoint[0] - cellBoundsWithSpacing.left;
|
||||
minRadius = Math.min(minRadius, centerPoint[1] - cellBoundsWithSpacing.top);
|
||||
minRadius = Math.min(minRadius, cellBoundsWithSpacing.right - centerPoint[0]);
|
||||
minRadius = Math.min(minRadius, cellBoundsWithSpacing.bottom - centerPoint[1]);
|
||||
return minRadius;
|
||||
}
|
||||
// Take up the entire cell, including space between this cell and the adjacent ones.
|
||||
return (float) Math.hypot(cellBoundsWithSpacing.width() / 2f,
|
||||
cellBoundsWithSpacing.height() / 2f);
|
||||
}
|
||||
|
||||
public int getCellWidth() {
|
||||
return mCellWidth;
|
||||
}
|
||||
|
||||
@@ -220,7 +220,6 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
private FolderIcon mDragOverFolderIcon = null;
|
||||
private boolean mCreateUserFolderOnDrop = false;
|
||||
private boolean mAddToExistingFolderOnDrop = false;
|
||||
private float mMaxDistanceForFolderCreation;
|
||||
|
||||
// Variables relating to touch disambiguation (scrolling workspace vs. scrolling a widget)
|
||||
private float mXDown;
|
||||
@@ -308,8 +307,6 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
public void setInsets(Rect insets) {
|
||||
DeviceProfile grid = mLauncher.getDeviceProfile();
|
||||
|
||||
mMaxDistanceForFolderCreation = grid.isTablet
|
||||
? 0.75f * grid.iconSizePx : 0.55f * grid.iconSizePx;
|
||||
mWorkspaceFadeInAdjacentScreens = grid.shouldFadeAdjacentWorkspaceScreens();
|
||||
|
||||
Rect padding = grid.workspacePadding;
|
||||
@@ -1774,8 +1771,8 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
mTargetCell = findNearestArea((int) mDragViewVisualCenter[0],
|
||||
(int) mDragViewVisualCenter[1], minSpanX, minSpanY, dropTargetLayout,
|
||||
mTargetCell);
|
||||
float distance = dropTargetLayout.getDistanceFromCell(mDragViewVisualCenter[0],
|
||||
mDragViewVisualCenter[1], mTargetCell);
|
||||
float distance = dropTargetLayout.getDistanceFromWorkspaceCellVisualCenter(
|
||||
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
|
||||
if (mCreateUserFolderOnDrop && willCreateUserFolder(d.dragInfo,
|
||||
dropTargetLayout, mTargetCell, distance, true)) {
|
||||
return true;
|
||||
@@ -1809,7 +1806,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
|
||||
boolean willCreateUserFolder(ItemInfo info, CellLayout target, int[] targetCell,
|
||||
float distance, boolean considerTimeout) {
|
||||
if (distance > mMaxDistanceForFolderCreation) return false;
|
||||
if (distance > target.getFolderCreationRadius(targetCell)) return false;
|
||||
View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
|
||||
return willCreateUserFolder(info, dropOverView, considerTimeout);
|
||||
}
|
||||
@@ -1844,7 +1841,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
|
||||
boolean willAddToExistingUserFolder(ItemInfo dragInfo, CellLayout target, int[] targetCell,
|
||||
float distance) {
|
||||
if (distance > mMaxDistanceForFolderCreation) return false;
|
||||
if (distance > target.getFolderCreationRadius(targetCell)) return false;
|
||||
View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
|
||||
return willAddToExistingUserFolder(dragInfo, dropOverView);
|
||||
|
||||
@@ -1868,7 +1865,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
|
||||
boolean createUserFolderIfNecessary(View newView, int container, CellLayout target,
|
||||
int[] targetCell, float distance, boolean external, DragObject d) {
|
||||
if (distance > mMaxDistanceForFolderCreation) return false;
|
||||
if (distance > target.getFolderCreationRadius(targetCell)) return false;
|
||||
View v = target.getChildAt(targetCell[0], targetCell[1]);
|
||||
|
||||
boolean hasntMoved = false;
|
||||
@@ -1925,7 +1922,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
|
||||
boolean addToExistingFolderIfNecessary(View newView, CellLayout target, int[] targetCell,
|
||||
float distance, DragObject d, boolean external) {
|
||||
if (distance > mMaxDistanceForFolderCreation) return false;
|
||||
if (distance > target.getFolderCreationRadius(targetCell)) return false;
|
||||
|
||||
View dropOverView = target.getChildAt(targetCell[0], targetCell[1]);
|
||||
if (!mAddToExistingFolderOnDrop) return false;
|
||||
@@ -1989,8 +1986,8 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
|
||||
mTargetCell = findNearestArea((int) mDragViewVisualCenter[0], (int)
|
||||
mDragViewVisualCenter[1], spanX, spanY, dropTargetLayout, mTargetCell);
|
||||
float distance = dropTargetLayout.getDistanceFromCell(mDragViewVisualCenter[0],
|
||||
mDragViewVisualCenter[1], mTargetCell);
|
||||
float distance = dropTargetLayout.getDistanceFromWorkspaceCellVisualCenter(
|
||||
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
|
||||
|
||||
// If the item being dropped is a shortcut and the nearest drop
|
||||
// cell also contains a shortcut, then create a folder with the two shortcuts.
|
||||
@@ -2418,7 +2415,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
|
||||
setCurrentDropOverCell(mTargetCell[0], mTargetCell[1]);
|
||||
|
||||
float targetCellDistance = mDragTargetLayout.getDistanceFromCell(
|
||||
float targetCellDistance = mDragTargetLayout.getDistanceFromWorkspaceCellVisualCenter(
|
||||
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
|
||||
|
||||
manageFolderFeedback(targetCellDistance, d);
|
||||
@@ -2431,8 +2428,9 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1],
|
||||
item.spanX, item.spanY, d);
|
||||
} else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER)
|
||||
&& !mReorderAlarm.alarmPending() && (mLastReorderX != reorderX ||
|
||||
mLastReorderY != reorderY)) {
|
||||
&& !mReorderAlarm.alarmPending()
|
||||
&& (mLastReorderX != reorderX || mLastReorderY != reorderY)
|
||||
&& targetCellDistance < mDragTargetLayout.getReorderRadius(mTargetCell)) {
|
||||
|
||||
int[] resultSpan = new int[2];
|
||||
mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
|
||||
@@ -2529,7 +2527,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
}
|
||||
|
||||
private void manageFolderFeedback(float distance, DragObject dragObject) {
|
||||
if (distance > mMaxDistanceForFolderCreation) {
|
||||
if (distance > mDragTargetLayout.getFolderCreationRadius(mTargetCell)) {
|
||||
if ((mDragMode == DRAG_MODE_ADD_TO_FOLDER
|
||||
|| mDragMode == DRAG_MODE_CREATE_FOLDER)) {
|
||||
setDragMode(DRAG_MODE_NONE);
|
||||
@@ -2674,8 +2672,8 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
if (pendingInfo.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
|
||||
mTargetCell = findNearestArea(touchXY[0], touchXY[1], spanX, spanY,
|
||||
cellLayout, mTargetCell);
|
||||
float distance = cellLayout.getDistanceFromCell(mDragViewVisualCenter[0],
|
||||
mDragViewVisualCenter[1], mTargetCell);
|
||||
float distance = cellLayout.getDistanceFromWorkspaceCellVisualCenter(
|
||||
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
|
||||
if (willCreateUserFolder(d.dragInfo, cellLayout, mTargetCell, distance, true)
|
||||
|| willAddToExistingUserFolder(
|
||||
d.dragInfo, cellLayout, mTargetCell, distance)) {
|
||||
@@ -2774,8 +2772,8 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
if (touchXY != null) {
|
||||
mTargetCell = findNearestArea(touchXY[0], touchXY[1], spanX, spanY,
|
||||
cellLayout, mTargetCell);
|
||||
float distance = cellLayout.getDistanceFromCell(mDragViewVisualCenter[0],
|
||||
mDragViewVisualCenter[1], mTargetCell);
|
||||
float distance = cellLayout.getDistanceFromWorkspaceCellVisualCenter(
|
||||
mDragViewVisualCenter[0], mDragViewVisualCenter[1], mTargetCell);
|
||||
if (createUserFolderIfNecessary(view, container, cellLayout, mTargetCell, distance,
|
||||
true, d)) {
|
||||
return;
|
||||
|
||||
@@ -72,6 +72,7 @@ public final class FeatureFlags {
|
||||
"PROMISE_APPS_NEW_INSTALLS", true,
|
||||
"Adds a promise icon to the home screen for new install sessions.");
|
||||
|
||||
// TODO: b/206508141: Long pressing on some icons on home screen cause launcher to crash.
|
||||
public static final BooleanFlag ENABLE_LOCAL_COLOR_POPUPS = getDebugFlag(
|
||||
"ENABLE_LOCAL_COLOR_POPUPS", false, "Enable local color extraction for popups.");
|
||||
|
||||
|
||||
@@ -77,44 +77,45 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
|
||||
extends AbstractFloatingView {
|
||||
|
||||
// Duration values (ms) for popup open and close animations.
|
||||
private static final int OPEN_DURATION = 276;
|
||||
private static final int OPEN_FADE_START_DELAY = 0;
|
||||
private static final int OPEN_FADE_DURATION = 38;
|
||||
private static final int OPEN_CHILD_FADE_START_DELAY = 38;
|
||||
private static final int OPEN_CHILD_FADE_DURATION = 76;
|
||||
protected int OPEN_DURATION = 276;
|
||||
protected int OPEN_FADE_START_DELAY = 0;
|
||||
protected int OPEN_FADE_DURATION = 38;
|
||||
protected int OPEN_CHILD_FADE_START_DELAY = 38;
|
||||
protected int OPEN_CHILD_FADE_DURATION = 76;
|
||||
|
||||
private static final int CLOSE_DURATION = 200;
|
||||
private static final int CLOSE_FADE_START_DELAY = 140;
|
||||
private static final int CLOSE_FADE_DURATION = 50;
|
||||
private static final int CLOSE_CHILD_FADE_START_DELAY = 0;
|
||||
private static final int CLOSE_CHILD_FADE_DURATION = 140;
|
||||
protected int CLOSE_DURATION = 200;
|
||||
protected int CLOSE_FADE_START_DELAY = 140;
|
||||
protected int CLOSE_FADE_DURATION = 50;
|
||||
protected int CLOSE_CHILD_FADE_START_DELAY = 0;
|
||||
protected int CLOSE_CHILD_FADE_DURATION = 140;
|
||||
|
||||
// Index used to get background color when using local wallpaper color extraction,
|
||||
private static final int DARK_COLOR_EXTRACTION_INDEX = android.R.color.system_neutral2_800;
|
||||
private static final int LIGHT_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_50;
|
||||
|
||||
private final Rect mTempRect = new Rect();
|
||||
protected final Rect mTempRect = new Rect();
|
||||
|
||||
protected final LayoutInflater mInflater;
|
||||
private final float mOutlineRadius;
|
||||
protected final float mOutlineRadius;
|
||||
protected final T mActivityContext;
|
||||
protected final boolean mIsRtl;
|
||||
|
||||
private final int mArrowOffsetVertical;
|
||||
private final int mArrowOffsetHorizontal;
|
||||
private final int mArrowWidth;
|
||||
private final int mArrowHeight;
|
||||
private final int mArrowPointRadius;
|
||||
private final View mArrow;
|
||||
protected final int mArrowOffsetVertical;
|
||||
protected final int mArrowOffsetHorizontal;
|
||||
protected final int mArrowWidth;
|
||||
protected final int mArrowHeight;
|
||||
protected final int mArrowPointRadius;
|
||||
protected final View mArrow;
|
||||
|
||||
private final int mMargin;
|
||||
|
||||
protected boolean mIsLeftAligned;
|
||||
protected boolean mIsAboveIcon;
|
||||
private int mGravity;
|
||||
protected int mGravity;
|
||||
|
||||
protected AnimatorSet mOpenCloseAnimator;
|
||||
protected boolean mDeferContainerRemoval;
|
||||
protected boolean shouldScaleArrow = false;
|
||||
|
||||
private final GradientDrawable mRoundedTop;
|
||||
private final GradientDrawable mRoundedBottom;
|
||||
@@ -122,10 +123,10 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
|
||||
private Runnable mOnCloseCallback = () -> { };
|
||||
|
||||
// The rect string of the view that the arrow is attached to, in screen reference frame.
|
||||
private int mArrowColor;
|
||||
protected int mArrowColor;
|
||||
protected final List<LocalColorExtractor> mColorExtractors;
|
||||
|
||||
private final float mElevation;
|
||||
protected final float mElevation;
|
||||
private final int mBackgroundColor;
|
||||
|
||||
private final String mIterateChildrenTag;
|
||||
@@ -729,6 +730,14 @@ public abstract class ArrowPopup<T extends Context & ActivityContext>
|
||||
scale.setInterpolator(interpolator);
|
||||
animatorSet.play(scale);
|
||||
|
||||
if (shouldScaleArrow) {
|
||||
Animator arrowScaleAnimator = ObjectAnimator.ofFloat(mArrow, View.SCALE_Y,
|
||||
scaleValues);
|
||||
arrowScaleAnimator.setDuration(totalDuration);
|
||||
arrowScaleAnimator.setInterpolator(interpolator);
|
||||
animatorSet.play(arrowScaleAnimator);
|
||||
}
|
||||
|
||||
fadeInChildViews(this, alphaValues, childFadeStartDelay, childFadeDuration, animatorSet);
|
||||
|
||||
return animatorSet;
|
||||
|
||||
@@ -78,6 +78,32 @@ public class RoundedArrowDrawable extends Drawable {
|
||||
mPath.transform(pathTransform);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for an arrow that points to the left or right.
|
||||
*
|
||||
* @param width of the arrow.
|
||||
* @param height of the arrow.
|
||||
* @param radius of the tip of the arrow.
|
||||
* @param isPointingLeft or not.
|
||||
* @param color to draw the triangle.
|
||||
*/
|
||||
public RoundedArrowDrawable(float width, float height, float radius, boolean isPointingLeft,
|
||||
int color) {
|
||||
mPath = new Path();
|
||||
mPaint = new Paint();
|
||||
mPaint.setColor(color);
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
mPaint.setAntiAlias(true);
|
||||
|
||||
// Make the drawable with the triangle pointing down...
|
||||
addDownPointingRoundedTriangleToPath(width, height, radius, mPath);
|
||||
|
||||
// ... then rotate it to the side it needs to point.
|
||||
Matrix pathTransform = new Matrix();
|
||||
pathTransform.setRotate(isPointingLeft ? 90 : -90, width * 0.5f, height * 0.5f);
|
||||
mPath.transform(pathTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
canvas.drawPath(mPath, mPaint);
|
||||
|
||||
@@ -429,7 +429,7 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
|
||||
|
||||
@Override
|
||||
public void setSplitIconParams(View primaryIconView, View secondaryIconView,
|
||||
int taskIconHeight, Rect primarySnapshotBounds, Rect secondarySnapshotBounds,
|
||||
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
|
||||
boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
|
||||
FrameLayout.LayoutParams primaryIconParams =
|
||||
(FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
|
||||
@@ -439,13 +439,12 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler {
|
||||
splitConfig.visualDividerBounds.height() :
|
||||
splitConfig.visualDividerBounds.width());
|
||||
|
||||
int primaryHeight = primarySnapshotBounds.height();
|
||||
primaryIconParams.gravity = (isRtl ? START : END) | TOP;
|
||||
primaryIconView.setTranslationY(primaryHeight - primaryIconView.getHeight() / 2f);
|
||||
primaryIconView.setTranslationY(primarySnapshotHeight - primaryIconView.getHeight() / 2f);
|
||||
primaryIconView.setTranslationX(0);
|
||||
|
||||
secondaryIconParams.gravity = (isRtl ? START : END) | TOP;
|
||||
secondaryIconView.setTranslationY(primaryHeight + taskIconHeight + dividerBar);
|
||||
secondaryIconView.setTranslationY(primarySnapshotHeight + taskIconHeight + dividerBar);
|
||||
secondaryIconView.setTranslationX(0);
|
||||
primaryIconView.setLayoutParams(primaryIconParams);
|
||||
secondaryIconView.setLayoutParams(secondaryIconParams);
|
||||
|
||||
@@ -152,7 +152,7 @@ public interface PagedOrientationHandler {
|
||||
void setIconAndSnapshotParams(View iconView, int taskIconMargin, int taskIconHeight,
|
||||
FrameLayout.LayoutParams snapshotParams, boolean isRtl);
|
||||
void setSplitIconParams(View primaryIconView, View secondaryIconView,
|
||||
int taskIconHeight, Rect primarySnapshotBounds, Rect secondarySnapshotBounds,
|
||||
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
|
||||
boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig);
|
||||
|
||||
/*
|
||||
|
||||
@@ -523,7 +523,7 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
|
||||
|
||||
@Override
|
||||
public void setSplitIconParams(View primaryIconView, View secondaryIconView,
|
||||
int taskIconHeight, Rect primarySnapshotBounds, Rect secondarySnapshotBounds,
|
||||
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
|
||||
boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
|
||||
FrameLayout.LayoutParams primaryIconParams =
|
||||
(FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
|
||||
@@ -533,15 +533,12 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
|
||||
splitConfig.visualDividerBounds.height() :
|
||||
splitConfig.visualDividerBounds.width());
|
||||
|
||||
int primaryWidth = primarySnapshotBounds.width();
|
||||
if (deviceProfile.isLandscape) {
|
||||
primaryIconParams.gravity = TOP | START;
|
||||
primaryIconView.setTranslationX(primaryWidth - primaryIconView.getWidth());
|
||||
primaryIconView.setTranslationX(primarySnapshotWidth - primaryIconView.getWidth());
|
||||
primaryIconView.setTranslationY(0);
|
||||
|
||||
secondaryIconParams.gravity = TOP | START;
|
||||
secondaryIconView.setTranslationX(primaryWidth + dividerBar);
|
||||
secondaryIconView.setTranslationY(0);
|
||||
secondaryIconView.setTranslationX(primarySnapshotWidth + dividerBar);
|
||||
} else {
|
||||
primaryIconParams.gravity = TOP | CENTER_HORIZONTAL;
|
||||
primaryIconView.setTranslationX(-(primaryIconView.getWidth()) / 2f);
|
||||
@@ -549,8 +546,8 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler {
|
||||
|
||||
secondaryIconParams.gravity = TOP | CENTER_HORIZONTAL;
|
||||
secondaryIconView.setTranslationX(secondaryIconView.getWidth() / 2f);
|
||||
secondaryIconView.setTranslationY(0);
|
||||
}
|
||||
secondaryIconView.setTranslationY(0);
|
||||
primaryIconView.setLayoutParams(primaryIconParams);
|
||||
secondaryIconView.setLayoutParams(secondaryIconParams);
|
||||
}
|
||||
|
||||
@@ -132,10 +132,10 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler {
|
||||
|
||||
@Override
|
||||
public void setSplitIconParams(View primaryIconView, View secondaryIconView,
|
||||
int taskIconHeight, Rect primarySnapshotBounds, Rect secondarySnapshotBounds,
|
||||
int taskIconHeight, int primarySnapshotWidth, int primarySnapshotHeight,
|
||||
boolean isRtl, DeviceProfile deviceProfile, StagedSplitBounds splitConfig) {
|
||||
super.setSplitIconParams(primaryIconView, secondaryIconView, taskIconHeight,
|
||||
primarySnapshotBounds, secondarySnapshotBounds, isRtl, deviceProfile, splitConfig);
|
||||
primarySnapshotWidth, primarySnapshotHeight, isRtl, deviceProfile, splitConfig);
|
||||
FrameLayout.LayoutParams primaryIconParams =
|
||||
(FrameLayout.LayoutParams) primaryIconView.getLayoutParams();
|
||||
FrameLayout.LayoutParams secondaryIconParams =
|
||||
|
||||
@@ -25,11 +25,15 @@ import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
import android.util.Size;
|
||||
|
||||
@@ -40,6 +44,7 @@ import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.icons.BitmapRenderer;
|
||||
import com.android.launcher3.icons.FastBitmapDrawable;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.icons.ShadowGenerator;
|
||||
import com.android.launcher3.icons.cache.HandlerRunnable;
|
||||
@@ -60,6 +65,9 @@ public class DatabaseWidgetPreviewLoader {
|
||||
private final Context mContext;
|
||||
private final float mPreviewBoxCornerRadius;
|
||||
|
||||
private final UserHandle mMyUser = Process.myUserHandle();
|
||||
private final ArrayMap<UserHandle, Bitmap> mUserBadges = new ArrayMap<>();
|
||||
|
||||
public DatabaseWidgetPreviewLoader(Context context) {
|
||||
mContext = context;
|
||||
float previewCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(context);
|
||||
@@ -100,6 +108,52 @@ public class DatabaseWidgetPreviewLoader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a drawable that can be used as a badge for the user or null.
|
||||
*/
|
||||
// @UiThread
|
||||
public Drawable getBadgeForUser(UserHandle user, int badgeSize) {
|
||||
if (mMyUser.equals(user)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Bitmap badgeBitmap = getUserBadge(user, badgeSize);
|
||||
FastBitmapDrawable d = new FastBitmapDrawable(badgeBitmap);
|
||||
d.setFilterBitmap(true);
|
||||
d.setBounds(0, 0, badgeBitmap.getWidth(), badgeBitmap.getHeight());
|
||||
return d;
|
||||
}
|
||||
|
||||
private Bitmap getUserBadge(UserHandle user, int badgeSize) {
|
||||
synchronized (mUserBadges) {
|
||||
Bitmap badgeBitmap = mUserBadges.get(user);
|
||||
if (badgeBitmap != null) {
|
||||
return badgeBitmap;
|
||||
}
|
||||
|
||||
final Resources res = mContext.getResources();
|
||||
badgeBitmap = Bitmap.createBitmap(badgeSize, badgeSize, Bitmap.Config.ARGB_8888);
|
||||
|
||||
Drawable drawable = mContext.getPackageManager().getUserBadgedDrawableForDensity(
|
||||
new BitmapDrawable(res, badgeBitmap), user,
|
||||
new Rect(0, 0, badgeSize, badgeSize),
|
||||
0);
|
||||
if (drawable instanceof BitmapDrawable) {
|
||||
badgeBitmap = ((BitmapDrawable) drawable).getBitmap();
|
||||
} else {
|
||||
badgeBitmap.eraseColor(Color.TRANSPARENT);
|
||||
Canvas c = new Canvas(badgeBitmap);
|
||||
drawable.setBounds(0, 0, badgeSize, badgeSize);
|
||||
drawable.draw(c);
|
||||
c.setBitmap(null);
|
||||
}
|
||||
|
||||
mUserBadges.put(user, badgeBitmap);
|
||||
return badgeBitmap;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generates the widget preview from either the {@link WidgetManagerHelper} or cache
|
||||
* and add badge at the bottom right corner.
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.view.ViewGroup;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RemoteViews;
|
||||
import android.widget.TextView;
|
||||
@@ -47,6 +48,7 @@ import com.android.launcher3.CheckLongPressHelper;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.icons.BaseIconFactory;
|
||||
import com.android.launcher3.icons.FastBitmapDrawable;
|
||||
import com.android.launcher3.icons.RoundDrawableWrapper;
|
||||
import com.android.launcher3.icons.cache.HandlerRunnable;
|
||||
@@ -111,6 +113,7 @@ public class WidgetCell extends LinearLayout {
|
||||
|
||||
private FrameLayout mWidgetImageContainer;
|
||||
private WidgetImageView mWidgetImage;
|
||||
private ImageView mWidgetBadge;
|
||||
private TextView mWidgetName;
|
||||
private TextView mWidgetDims;
|
||||
private TextView mWidgetDescription;
|
||||
@@ -166,6 +169,7 @@ public class WidgetCell extends LinearLayout {
|
||||
|
||||
mWidgetImageContainer = findViewById(R.id.widget_preview_container);
|
||||
mWidgetImage = findViewById(R.id.widget_preview);
|
||||
mWidgetBadge = findViewById(R.id.widget_badge);
|
||||
mWidgetName = findViewById(R.id.widget_name);
|
||||
mWidgetDims = findViewById(R.id.widget_dims);
|
||||
mWidgetDescription = findViewById(R.id.widget_description);
|
||||
@@ -195,6 +199,8 @@ public class WidgetCell extends LinearLayout {
|
||||
mWidgetImage.animate().cancel();
|
||||
mWidgetImage.setDrawable(null);
|
||||
mWidgetImage.setVisibility(View.VISIBLE);
|
||||
mWidgetBadge.setImageDrawable(null);
|
||||
mWidgetBadge.setVisibility(View.GONE);
|
||||
mWidgetName.setText(null);
|
||||
mWidgetDims.setText(null);
|
||||
mWidgetDescription.setText(null);
|
||||
@@ -349,6 +355,7 @@ public class WidgetCell extends LinearLayout {
|
||||
mAppWidgetHostViewPreview = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (mAnimatePreview) {
|
||||
mWidgetImageContainer.setAlpha(0f);
|
||||
ViewPropertyAnimator anim = mWidgetImageContainer.animate();
|
||||
@@ -362,6 +369,20 @@ public class WidgetCell extends LinearLayout {
|
||||
}
|
||||
}
|
||||
|
||||
/** Used to show the badge when the widget is in the recommended section
|
||||
*/
|
||||
public void showBadge() {
|
||||
Drawable badge = mWidgetPreviewLoader.getBadgeForUser(mItem.user,
|
||||
BaseIconFactory.getBadgeSizeForIconSize(
|
||||
mActivity.getDeviceProfile().allAppsIconSizePx));
|
||||
if (badge == null) {
|
||||
mWidgetBadge.setVisibility(View.GONE);
|
||||
} else {
|
||||
mWidgetBadge.setVisibility(View.VISIBLE);
|
||||
mWidgetBadge.setImageDrawable(badge);
|
||||
}
|
||||
}
|
||||
|
||||
private void setContainerSize(int width, int height) {
|
||||
LayoutParams layoutParams = (LayoutParams) mWidgetImageContainer.getLayoutParams();
|
||||
layoutParams.width = width;
|
||||
|
||||
@@ -109,6 +109,7 @@ public final class WidgetsRecommendationTableLayout extends TableLayout {
|
||||
for (WidgetItem widgetItem : widgetItems) {
|
||||
WidgetCell widgetCell = addItemCell(tableRow);
|
||||
widgetCell.applyFromCellItem(widgetItem, data.mPreviewScale);
|
||||
widgetCell.showBadge();
|
||||
}
|
||||
addView(tableRow);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class TestStabilityRule implements TestRule {
|
||||
Pattern.compile("^("
|
||||
+ "(?<local>(BuildFromAndroidStudio|"
|
||||
+ "([0-9]+|[A-Z])-eng\\.[a-z]+\\.[0-9]+\\.[0-9]+))|"
|
||||
+ "(?<platform>[A-Z]([a-z]|[0-9])*)"
|
||||
+ "(?<platform>([A-Z][a-z]*[0-9]*|[0-9]+)*)"
|
||||
+ ")$");
|
||||
private static final Pattern PLATFORM_BUILD =
|
||||
Pattern.compile("^("
|
||||
|
||||
Reference in New Issue
Block a user