Loading quickstep/src/com/android/quickstep/views/FloatingTaskThumbnailView.java 0 → 100644 +86 −0 Original line number Diff line number Diff line /* * Copyright 2022 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.quickstep.views; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Shader; import android.util.AttributeSet; import android.view.View; import androidx.annotation.Nullable; /** * A child view of {@link com.android.quickstep.views.FloatingTaskView} to draw the thumbnail in a * rounded corner frame. While the purpose of this class sounds similar to * {@link TaskThumbnailView}, it doesn't need a lot of complex logic in {@link TaskThumbnailView} * in relation to moving with {@link RecentsView}. */ public class FloatingTaskThumbnailView extends View { private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Matrix mMatrix = new Matrix(); private @Nullable BitmapShader mBitmapShader; private @Nullable Bitmap mBitmap; private FloatingTaskView.FullscreenDrawParams mFullscreenParams; public FloatingTaskThumbnailView(Context context) { this(context, null); } public FloatingTaskThumbnailView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FloatingTaskThumbnailView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { if (mFullscreenParams == null || mBitmap == null) { return; } // Scale down the bitmap to fix x, and crop in y. float scale = 1.0f * getMeasuredWidth() / mBitmap.getWidth(); mMatrix.postScale(scale, scale); mBitmapShader.setLocalMatrix(mMatrix); canvas.drawRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleX, mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleY, mPaint); } public void setThumbnail(Bitmap bitmap) { mBitmap = bitmap; if (bitmap != null) { mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mPaint.setShader(mBitmapShader); } } public void setFullscreenParams(FloatingTaskView.FullscreenDrawParams fullscreenParams) { mFullscreenParams = fullscreenParams; } } quickstep/src/com/android/quickstep/views/FloatingTaskView.java +52 −28 Original line number Diff line number Diff line Loading @@ -15,7 +15,6 @@ import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageView; import androidx.annotation.Nullable; Loading @@ -29,6 +28,8 @@ import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.views.BaseDragLayer; import com.android.quickstep.util.MultiValueUpdateListener; import com.android.quickstep.util.TaskCornerRadius; import com.android.systemui.shared.system.QuickStepContract; import java.util.function.Consumer; Loading @@ -50,9 +51,9 @@ public class FloatingTaskView extends FrameLayout { private RectF mStartingPosition; private final StatefulActivity mActivity; private final boolean mIsRtl; private final Rect mOutline = new Rect(); private final FullscreenDrawParams mCurrentFullscreenParams; private PagedOrientationHandler mOrientationHandler; private ImageView mImageView; private FloatingTaskThumbnailView mThumbnailView; public FloatingTaskView(Context context) { this(context, null); Loading @@ -66,16 +67,17 @@ public class FloatingTaskView extends FrameLayout { super(context, attrs, defStyleAttr); mActivity = BaseActivity.fromContext(context); mIsRtl = Utilities.isRtl(getResources()); mCurrentFullscreenParams = new FullscreenDrawParams(context); } @Override protected void onFinishInflate() { super.onFinishInflate(); mImageView = findViewById(R.id.thumbnail); mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP); mImageView.setLayerType(LAYER_TYPE_HARDWARE, null); mThumbnailView = findViewById(R.id.thumbnail); mThumbnailView.setFullscreenParams(mCurrentFullscreenParams); mSplitPlaceholderView = findViewById(R.id.split_placeholder); mSplitPlaceholderView.setAlpha(0); mSplitPlaceholderView.setFullscreenParams(mCurrentFullscreenParams); } private void init(StatefulActivity launcher, View originalView, @Nullable Bitmap thumbnail, Loading @@ -86,13 +88,11 @@ public class FloatingTaskView extends FrameLayout { (InsettableFrameLayout.LayoutParams) getLayoutParams(); mSplitPlaceholderView.setLayoutParams(new FrameLayout.LayoutParams(lp.width, lp.height)); positionOut.round(mOutline); setPivotX(0); setPivotY(0); // Copy bounds of exiting thumbnail into ImageView mImageView.setImageBitmap(thumbnail); mImageView.setVisibility(VISIBLE); mThumbnailView.setThumbnail(thumbnail); RecentsView recentsView = launcher.getOverviewPanel(); mOrientationHandler = recentsView.getPagedOrientationHandler(); Loading Loading @@ -133,27 +133,24 @@ public class FloatingTaskView extends FrameLayout { setLayoutParams(lp); } // TODO(194414938) set correct corner radii public void update(RectF position, float progress, float windowRadius) { public void update(RectF position, float progress) { MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams(); float dX = position.left - mStartingPosition.left; float dY = position.top - lp.topMargin; float scaleX = position.width() / lp.width; float scaleY = position.height() / lp.height; mCurrentFullscreenParams.updateParams(position, progress, scaleX, scaleY); setTranslationX(dX); setTranslationY(dY); float scaleX = position.width() / lp.width; float scaleY = position.height() / lp.height; setScaleX(scaleX); setScaleY(scaleY); mSplitPlaceholderView.invalidate(); float childScaleX = 1f / scaleX; float childScaleY = 1f / scaleY; invalidate(); // TODO(194414938) seems like this scale value could be fine tuned, some stretchiness mImageView.setScaleX(1f / scaleX + scaleX * progress); mImageView.setScaleY(1f / scaleY + scaleY * progress); mOrientationHandler.setPrimaryScale(mSplitPlaceholderView.getIconView(), childScaleX); mOrientationHandler.setSecondaryScale(mSplitPlaceholderView.getIconView(), childScaleY); } Loading Loading @@ -181,7 +178,8 @@ public class FloatingTaskView extends FrameLayout { } public void addAnimation(PendingAnimation animation, RectF startingBounds, Rect endBounds, boolean fadeWithThumbnail) { boolean fadeWithThumbnail, boolean isInitialSplit) { mCurrentFullscreenParams.setIsInitialSplit(isInitialSplit); final BaseDragLayer dragLayer = mActivity.getDragLayer(); int[] dragLayerBounds = new int[2]; dragLayer.getLocationOnScreen(dragLayerBounds); Loading @@ -191,22 +189,16 @@ public class FloatingTaskView extends FrameLayout { ValueAnimator transitionAnimator = ValueAnimator.ofFloat(0, 1); animation.add(transitionAnimator); long animDuration = animation.getDuration(); Rect crop = new Rect(); RectF floatingTaskViewBounds = new RectF(); final float initialWindowRadius = supportsRoundedCornersOnWindows(getResources()) ? Math.max(crop.width(), crop.height()) / 2f : 0f; if (fadeWithThumbnail) { animation.addFloat(mSplitPlaceholderView, SplitPlaceholderView.ALPHA_FLOAT, 0, 1, ACCEL); animation.addFloat(mImageView, LauncherAnimUtils.VIEW_ALPHA, animation.addFloat(mThumbnailView, LauncherAnimUtils.VIEW_ALPHA, 1, 0, DEACCEL_3); } MultiValueUpdateListener listener = new MultiValueUpdateListener() { final FloatProp mWindowRadius = new FloatProp(initialWindowRadius, initialWindowRadius, 0, animDuration, LINEAR); final FloatProp mDx = new FloatProp(0, prop.dX, 0, animDuration, LINEAR); final FloatProp mDy = new FloatProp(0, prop.dY, 0, animDuration, LINEAR); final FloatProp mTaskViewScaleX = new FloatProp(1f, prop.finalTaskViewScaleX, 0, Loading @@ -221,7 +213,7 @@ public class FloatingTaskView extends FrameLayout { Utilities.scaleRectFAboutCenter(floatingTaskViewBounds, mTaskViewScaleX.value, mTaskViewScaleY.value); update(floatingTaskViewBounds, percent, mWindowRadius.value * 1); update(floatingTaskViewBounds, percent); } }; transitionAnimator.addUpdateListener(listener); Loading Loading @@ -250,4 +242,36 @@ public class FloatingTaskView extends FrameLayout { dY = centerY - startTaskViewBounds.centerY(); } } public static class FullscreenDrawParams { private final float mCornerRadius; private final float mWindowCornerRadius; public boolean mIsInitialSplit = true; public final RectF mFloatingTaskViewBounds = new RectF(); public float mCurrentDrawnCornerRadius; public float mScaleX = 1; public float mScaleY = 1; public FullscreenDrawParams(Context context) { mCornerRadius = TaskCornerRadius.get(context); mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context); mCurrentDrawnCornerRadius = mCornerRadius; } public void updateParams(RectF floatingTaskViewBounds, float progress, float scaleX, float scaleY) { mFloatingTaskViewBounds.set(floatingTaskViewBounds); mScaleX = scaleX; mScaleY = scaleY; mCurrentDrawnCornerRadius = mIsInitialSplit ? 0 : Utilities.mapRange(progress, mCornerRadius, mWindowCornerRadius); } public void setIsInitialSplit(boolean isInitialSplit) { mIsInitialSplit = isInitialSplit; } } } quickstep/src/com/android/quickstep/views/RecentsView.java +5 −5 Original line number Diff line number Diff line Loading @@ -2732,7 +2732,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect); mFirstFloatingTaskView.setAlpha(1); mFirstFloatingTaskView.addAnimation(anim, startingTaskRect, mTempRect, true /*fadeWithThumbnail*/); mTempRect, true /* fadeWithThumbnail */, true /* isInitialSplit */); } else { mSplitSelectSource.view.setVisibility(INVISIBLE); mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity, Loading @@ -2740,7 +2740,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mSplitSelectSource.drawable, startingTaskRect); mFirstFloatingTaskView.setAlpha(1); mFirstFloatingTaskView.addAnimation(anim, startingTaskRect, mTempRect, true /*fadeWithThumbnail*/); mTempRect, true /* fadeWithThumbnail */, true /* isInitialSplit */); } anim.addEndListener(success -> { if (success) { Loading Loading @@ -4030,14 +4030,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mFirstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds); mFirstFloatingTaskView.addAnimation(pendingAnimation, new RectF(firstTaskStartingBounds), firstTaskEndingBounds, false /*fadeWithThumbnail*/); false /* fadeWithThumbnail */, false /* isInitialSplit */); mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity, thumbnailView, thumbnailView.getThumbnail(), iconView.getDrawable(), secondTaskStartingBounds); mSecondFloatingTaskView.setAlpha(1); mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds, secondTaskEndingBounds, true /* fadeWithThumbnail */); secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isInitialSplit */); pendingAnimation.addEndListener(aBoolean -> mSplitSelectStateController.setSecondTaskId(task.key.id, aBoolean1 -> RecentsView.this.resetFromSplitSelectionState())); Loading Loading @@ -4110,7 +4110,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mTempRectF.set(mTempRect); // TODO(194414938) set correct corner radius mFirstFloatingTaskView.updateOrientationHandler(mOrientationHandler); mFirstFloatingTaskView.update(mTempRectF, /*progress=*/1f, /*windowRadius=*/0f); mFirstFloatingTaskView.update(mTempRectF, /*progress=*/1f); PagedOrientationHandler orientationHandler = getPagedOrientationHandler(); Pair<FloatProperty, FloatProperty> taskViewsFloat = Loading quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java +38 −0 Original line number Diff line number Diff line Loading @@ -17,9 +17,12 @@ package com.android.quickstep.views; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.TypedValue; import android.view.Gravity; import android.widget.FrameLayout; Loading @@ -27,6 +30,10 @@ import androidx.annotation.Nullable; public class SplitPlaceholderView extends FrameLayout { private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private FloatingTaskView.FullscreenDrawParams mFullscreenParams; public static final FloatProperty<SplitPlaceholderView> ALPHA_FLOAT = new FloatProperty<SplitPlaceholderView>("SplitViewAlpha") { @Override Loading @@ -46,6 +53,17 @@ public class SplitPlaceholderView extends FrameLayout { public SplitPlaceholderView(Context context, AttributeSet attrs) { super(context, attrs); mPaint.setColor(getThemePrimaryColor(context)); setWillNotDraw(false); } @Override protected void dispatchDraw(Canvas canvas) { // Call this before super call to draw below the children. drawBackground(canvas); super.dispatchDraw(canvas); } @Nullable Loading @@ -53,6 +71,10 @@ public class SplitPlaceholderView extends FrameLayout { return mIconView; } public void setFullscreenParams(FloatingTaskView.FullscreenDrawParams fullscreenParams) { mFullscreenParams = fullscreenParams; } public void setIcon(Drawable drawable, int iconSize) { if (mIconView == null) { mIconView = new IconView(getContext()); Loading @@ -64,4 +86,20 @@ public class SplitPlaceholderView extends FrameLayout { params.gravity = Gravity.CENTER; mIconView.setLayoutParams(params); } private void drawBackground(Canvas canvas) { if (mFullscreenParams == null) { return; } canvas.drawRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleX, mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleY, mPaint); } private static int getThemePrimaryColor(Context context) { final TypedValue value = new TypedValue(); context.getTheme().resolveAttribute(android.R.attr.colorPrimary, value, true); return value.data; } } res/layout/floating_split_select_view.xml +1 −2 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView <com.android.quickstep.views.FloatingTaskThumbnailView android:id="@+id/thumbnail" android:layout_width="match_parent" android:layout_height="match_parent" Loading @@ -14,7 +14,6 @@ android:id="@+id/split_placeholder" android:layout_width="match_parent" android:layout_height="@dimen/split_placeholder_size" android:background="?android:colorPrimary" android:visibility="gone" /> </com.android.quickstep.views.FloatingTaskView> No newline at end of file Loading
quickstep/src/com/android/quickstep/views/FloatingTaskThumbnailView.java 0 → 100644 +86 −0 Original line number Diff line number Diff line /* * Copyright 2022 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.quickstep.views; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Shader; import android.util.AttributeSet; import android.view.View; import androidx.annotation.Nullable; /** * A child view of {@link com.android.quickstep.views.FloatingTaskView} to draw the thumbnail in a * rounded corner frame. While the purpose of this class sounds similar to * {@link TaskThumbnailView}, it doesn't need a lot of complex logic in {@link TaskThumbnailView} * in relation to moving with {@link RecentsView}. */ public class FloatingTaskThumbnailView extends View { private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private final Matrix mMatrix = new Matrix(); private @Nullable BitmapShader mBitmapShader; private @Nullable Bitmap mBitmap; private FloatingTaskView.FullscreenDrawParams mFullscreenParams; public FloatingTaskThumbnailView(Context context) { this(context, null); } public FloatingTaskThumbnailView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FloatingTaskThumbnailView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onDraw(Canvas canvas) { if (mFullscreenParams == null || mBitmap == null) { return; } // Scale down the bitmap to fix x, and crop in y. float scale = 1.0f * getMeasuredWidth() / mBitmap.getWidth(); mMatrix.postScale(scale, scale); mBitmapShader.setLocalMatrix(mMatrix); canvas.drawRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleX, mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleY, mPaint); } public void setThumbnail(Bitmap bitmap) { mBitmap = bitmap; if (bitmap != null) { mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); mPaint.setShader(mBitmapShader); } } public void setFullscreenParams(FloatingTaskView.FullscreenDrawParams fullscreenParams) { mFullscreenParams = fullscreenParams; } }
quickstep/src/com/android/quickstep/views/FloatingTaskView.java +52 −28 Original line number Diff line number Diff line Loading @@ -15,7 +15,6 @@ import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.ImageView; import androidx.annotation.Nullable; Loading @@ -29,6 +28,8 @@ import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.views.BaseDragLayer; import com.android.quickstep.util.MultiValueUpdateListener; import com.android.quickstep.util.TaskCornerRadius; import com.android.systemui.shared.system.QuickStepContract; import java.util.function.Consumer; Loading @@ -50,9 +51,9 @@ public class FloatingTaskView extends FrameLayout { private RectF mStartingPosition; private final StatefulActivity mActivity; private final boolean mIsRtl; private final Rect mOutline = new Rect(); private final FullscreenDrawParams mCurrentFullscreenParams; private PagedOrientationHandler mOrientationHandler; private ImageView mImageView; private FloatingTaskThumbnailView mThumbnailView; public FloatingTaskView(Context context) { this(context, null); Loading @@ -66,16 +67,17 @@ public class FloatingTaskView extends FrameLayout { super(context, attrs, defStyleAttr); mActivity = BaseActivity.fromContext(context); mIsRtl = Utilities.isRtl(getResources()); mCurrentFullscreenParams = new FullscreenDrawParams(context); } @Override protected void onFinishInflate() { super.onFinishInflate(); mImageView = findViewById(R.id.thumbnail); mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP); mImageView.setLayerType(LAYER_TYPE_HARDWARE, null); mThumbnailView = findViewById(R.id.thumbnail); mThumbnailView.setFullscreenParams(mCurrentFullscreenParams); mSplitPlaceholderView = findViewById(R.id.split_placeholder); mSplitPlaceholderView.setAlpha(0); mSplitPlaceholderView.setFullscreenParams(mCurrentFullscreenParams); } private void init(StatefulActivity launcher, View originalView, @Nullable Bitmap thumbnail, Loading @@ -86,13 +88,11 @@ public class FloatingTaskView extends FrameLayout { (InsettableFrameLayout.LayoutParams) getLayoutParams(); mSplitPlaceholderView.setLayoutParams(new FrameLayout.LayoutParams(lp.width, lp.height)); positionOut.round(mOutline); setPivotX(0); setPivotY(0); // Copy bounds of exiting thumbnail into ImageView mImageView.setImageBitmap(thumbnail); mImageView.setVisibility(VISIBLE); mThumbnailView.setThumbnail(thumbnail); RecentsView recentsView = launcher.getOverviewPanel(); mOrientationHandler = recentsView.getPagedOrientationHandler(); Loading Loading @@ -133,27 +133,24 @@ public class FloatingTaskView extends FrameLayout { setLayoutParams(lp); } // TODO(194414938) set correct corner radii public void update(RectF position, float progress, float windowRadius) { public void update(RectF position, float progress) { MarginLayoutParams lp = (MarginLayoutParams) getLayoutParams(); float dX = position.left - mStartingPosition.left; float dY = position.top - lp.topMargin; float scaleX = position.width() / lp.width; float scaleY = position.height() / lp.height; mCurrentFullscreenParams.updateParams(position, progress, scaleX, scaleY); setTranslationX(dX); setTranslationY(dY); float scaleX = position.width() / lp.width; float scaleY = position.height() / lp.height; setScaleX(scaleX); setScaleY(scaleY); mSplitPlaceholderView.invalidate(); float childScaleX = 1f / scaleX; float childScaleY = 1f / scaleY; invalidate(); // TODO(194414938) seems like this scale value could be fine tuned, some stretchiness mImageView.setScaleX(1f / scaleX + scaleX * progress); mImageView.setScaleY(1f / scaleY + scaleY * progress); mOrientationHandler.setPrimaryScale(mSplitPlaceholderView.getIconView(), childScaleX); mOrientationHandler.setSecondaryScale(mSplitPlaceholderView.getIconView(), childScaleY); } Loading Loading @@ -181,7 +178,8 @@ public class FloatingTaskView extends FrameLayout { } public void addAnimation(PendingAnimation animation, RectF startingBounds, Rect endBounds, boolean fadeWithThumbnail) { boolean fadeWithThumbnail, boolean isInitialSplit) { mCurrentFullscreenParams.setIsInitialSplit(isInitialSplit); final BaseDragLayer dragLayer = mActivity.getDragLayer(); int[] dragLayerBounds = new int[2]; dragLayer.getLocationOnScreen(dragLayerBounds); Loading @@ -191,22 +189,16 @@ public class FloatingTaskView extends FrameLayout { ValueAnimator transitionAnimator = ValueAnimator.ofFloat(0, 1); animation.add(transitionAnimator); long animDuration = animation.getDuration(); Rect crop = new Rect(); RectF floatingTaskViewBounds = new RectF(); final float initialWindowRadius = supportsRoundedCornersOnWindows(getResources()) ? Math.max(crop.width(), crop.height()) / 2f : 0f; if (fadeWithThumbnail) { animation.addFloat(mSplitPlaceholderView, SplitPlaceholderView.ALPHA_FLOAT, 0, 1, ACCEL); animation.addFloat(mImageView, LauncherAnimUtils.VIEW_ALPHA, animation.addFloat(mThumbnailView, LauncherAnimUtils.VIEW_ALPHA, 1, 0, DEACCEL_3); } MultiValueUpdateListener listener = new MultiValueUpdateListener() { final FloatProp mWindowRadius = new FloatProp(initialWindowRadius, initialWindowRadius, 0, animDuration, LINEAR); final FloatProp mDx = new FloatProp(0, prop.dX, 0, animDuration, LINEAR); final FloatProp mDy = new FloatProp(0, prop.dY, 0, animDuration, LINEAR); final FloatProp mTaskViewScaleX = new FloatProp(1f, prop.finalTaskViewScaleX, 0, Loading @@ -221,7 +213,7 @@ public class FloatingTaskView extends FrameLayout { Utilities.scaleRectFAboutCenter(floatingTaskViewBounds, mTaskViewScaleX.value, mTaskViewScaleY.value); update(floatingTaskViewBounds, percent, mWindowRadius.value * 1); update(floatingTaskViewBounds, percent); } }; transitionAnimator.addUpdateListener(listener); Loading Loading @@ -250,4 +242,36 @@ public class FloatingTaskView extends FrameLayout { dY = centerY - startTaskViewBounds.centerY(); } } public static class FullscreenDrawParams { private final float mCornerRadius; private final float mWindowCornerRadius; public boolean mIsInitialSplit = true; public final RectF mFloatingTaskViewBounds = new RectF(); public float mCurrentDrawnCornerRadius; public float mScaleX = 1; public float mScaleY = 1; public FullscreenDrawParams(Context context) { mCornerRadius = TaskCornerRadius.get(context); mWindowCornerRadius = QuickStepContract.getWindowCornerRadius(context); mCurrentDrawnCornerRadius = mCornerRadius; } public void updateParams(RectF floatingTaskViewBounds, float progress, float scaleX, float scaleY) { mFloatingTaskViewBounds.set(floatingTaskViewBounds); mScaleX = scaleX; mScaleY = scaleY; mCurrentDrawnCornerRadius = mIsInitialSplit ? 0 : Utilities.mapRange(progress, mCornerRadius, mWindowCornerRadius); } public void setIsInitialSplit(boolean isInitialSplit) { mIsInitialSplit = isInitialSplit; } } }
quickstep/src/com/android/quickstep/views/RecentsView.java +5 −5 Original line number Diff line number Diff line Loading @@ -2732,7 +2732,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mSplitHiddenTaskView.getIconView().getDrawable(), startingTaskRect); mFirstFloatingTaskView.setAlpha(1); mFirstFloatingTaskView.addAnimation(anim, startingTaskRect, mTempRect, true /*fadeWithThumbnail*/); mTempRect, true /* fadeWithThumbnail */, true /* isInitialSplit */); } else { mSplitSelectSource.view.setVisibility(INVISIBLE); mFirstFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity, Loading @@ -2740,7 +2740,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mSplitSelectSource.drawable, startingTaskRect); mFirstFloatingTaskView.setAlpha(1); mFirstFloatingTaskView.addAnimation(anim, startingTaskRect, mTempRect, true /*fadeWithThumbnail*/); mTempRect, true /* fadeWithThumbnail */, true /* isInitialSplit */); } anim.addEndListener(success -> { if (success) { Loading Loading @@ -4030,14 +4030,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mFirstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds); mFirstFloatingTaskView.addAnimation(pendingAnimation, new RectF(firstTaskStartingBounds), firstTaskEndingBounds, false /*fadeWithThumbnail*/); false /* fadeWithThumbnail */, false /* isInitialSplit */); mSecondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mActivity, thumbnailView, thumbnailView.getThumbnail(), iconView.getDrawable(), secondTaskStartingBounds); mSecondFloatingTaskView.setAlpha(1); mSecondFloatingTaskView.addAnimation(pendingAnimation, secondTaskStartingBounds, secondTaskEndingBounds, true /* fadeWithThumbnail */); secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isInitialSplit */); pendingAnimation.addEndListener(aBoolean -> mSplitSelectStateController.setSecondTaskId(task.key.id, aBoolean1 -> RecentsView.this.resetFromSplitSelectionState())); Loading Loading @@ -4110,7 +4110,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T mTempRectF.set(mTempRect); // TODO(194414938) set correct corner radius mFirstFloatingTaskView.updateOrientationHandler(mOrientationHandler); mFirstFloatingTaskView.update(mTempRectF, /*progress=*/1f, /*windowRadius=*/0f); mFirstFloatingTaskView.update(mTempRectF, /*progress=*/1f); PagedOrientationHandler orientationHandler = getPagedOrientationHandler(); Pair<FloatProperty, FloatProperty> taskViewsFloat = Loading
quickstep/src/com/android/quickstep/views/SplitPlaceholderView.java +38 −0 Original line number Diff line number Diff line Loading @@ -17,9 +17,12 @@ package com.android.quickstep.views; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.TypedValue; import android.view.Gravity; import android.widget.FrameLayout; Loading @@ -27,6 +30,10 @@ import androidx.annotation.Nullable; public class SplitPlaceholderView extends FrameLayout { private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private FloatingTaskView.FullscreenDrawParams mFullscreenParams; public static final FloatProperty<SplitPlaceholderView> ALPHA_FLOAT = new FloatProperty<SplitPlaceholderView>("SplitViewAlpha") { @Override Loading @@ -46,6 +53,17 @@ public class SplitPlaceholderView extends FrameLayout { public SplitPlaceholderView(Context context, AttributeSet attrs) { super(context, attrs); mPaint.setColor(getThemePrimaryColor(context)); setWillNotDraw(false); } @Override protected void dispatchDraw(Canvas canvas) { // Call this before super call to draw below the children. drawBackground(canvas); super.dispatchDraw(canvas); } @Nullable Loading @@ -53,6 +71,10 @@ public class SplitPlaceholderView extends FrameLayout { return mIconView; } public void setFullscreenParams(FloatingTaskView.FullscreenDrawParams fullscreenParams) { mFullscreenParams = fullscreenParams; } public void setIcon(Drawable drawable, int iconSize) { if (mIconView == null) { mIconView = new IconView(getContext()); Loading @@ -64,4 +86,20 @@ public class SplitPlaceholderView extends FrameLayout { params.gravity = Gravity.CENTER; mIconView.setLayoutParams(params); } private void drawBackground(Canvas canvas) { if (mFullscreenParams == null) { return; } canvas.drawRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleX, mFullscreenParams.mCurrentDrawnCornerRadius / mFullscreenParams.mScaleY, mPaint); } private static int getThemePrimaryColor(Context context) { final TypedValue value = new TypedValue(); context.getTheme().resolveAttribute(android.R.attr.colorPrimary, value, true); return value.data; } }
res/layout/floating_split_select_view.xml +1 −2 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView <com.android.quickstep.views.FloatingTaskThumbnailView android:id="@+id/thumbnail" android:layout_width="match_parent" android:layout_height="match_parent" Loading @@ -14,7 +14,6 @@ android:id="@+id/split_placeholder" android:layout_width="match_parent" android:layout_height="@dimen/split_placeholder_size" android:background="?android:colorPrimary" android:visibility="gone" /> </com.android.quickstep.views.FloatingTaskView> No newline at end of file