Snap for 9781601 from 4202d43e48 to udc-release
Change-Id: Id00b644604756efe5cb4042f6899cabc75aadfd6
This commit is contained in:
@@ -103,6 +103,7 @@
|
||||
<activity android:name="com.android.quickstep.interaction.GestureSandboxActivity"
|
||||
android:autoRemoveFromRecents="true"
|
||||
android:excludeFromRecents="true"
|
||||
android:theme="@style/GestureTutorialActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="com.android.quickstep.action.GESTURE_SANDBOX"/>
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2023 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.
|
||||
-->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingVertical="26dp"
|
||||
android:paddingHorizontal="56dp">
|
||||
|
||||
<View
|
||||
android:id="@+id/hotseat_icon_1"
|
||||
android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:background="@drawable/hotseat_icon_home"
|
||||
android:clipToOutline="true"
|
||||
|
||||
app:layout_constraintBottom_toTopOf="@id/hotseat_icon_2"
|
||||
app:layout_constraintVertical_chainStyle="spread_inside"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/hotseat_icon_2"
|
||||
android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:background="@drawable/hotseat_icon_home"
|
||||
android:clipToOutline="true"
|
||||
|
||||
app:layout_constraintBottom_toTopOf="@id/hotseat_icon_3"
|
||||
app:layout_constraintTop_toBottomOf="@id/hotseat_icon_1"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/hotseat_icon_3"
|
||||
android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:background="@drawable/hotseat_icon_home"
|
||||
android:clipToOutline="true"
|
||||
|
||||
app:layout_constraintBottom_toTopOf="@id/hotseat_icon_4"
|
||||
app:layout_constraintTop_toBottomOf="@id/hotseat_icon_2"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<View
|
||||
android:id="@+id/hotseat_icon_4"
|
||||
android:layout_width="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:layout_height="@dimen/gesture_tutorial_hotseat_icon_size"
|
||||
android:background="@drawable/hotseat_icon_home"
|
||||
android:clipToOutline="true"
|
||||
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/hotseat_icon_3"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2023 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.
|
||||
-->
|
||||
<View
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/back_gesture_tutorial_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
@@ -118,6 +118,14 @@
|
||||
android:scaleType="fitXY"
|
||||
android:visibility="gone" />
|
||||
|
||||
<View
|
||||
android:id="@+id/exiting_app_back"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerVertical="true"
|
||||
android:background="@color/gesture_back_tutorial_exiting_app"
|
||||
android:visibility="gone" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/full_gesture_demonstration"
|
||||
android:layout_width="match_parent"
|
||||
@@ -193,43 +201,33 @@
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_fragment_feedback_subtitle" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/gesture_tutorial_checkbox_bg"
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/checkmark_animation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="48dp"
|
||||
android:layout_marginTop="100dp"
|
||||
android:background="@drawable/gesture_tutorial_complete_checkmark_bg"
|
||||
android:gravity="center"
|
||||
android:scaleType="centerCrop"
|
||||
app:lottie_loop="false"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/gesture_tutorial_fragment_action_button"
|
||||
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_fragment_feedback_subtitle" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/gesture_tutorial_checkbox"
|
||||
android:layout_width="124dp"
|
||||
android:layout_height="124dp"
|
||||
android:background="@drawable/gesture_tutorial_complete_checkmark"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/gesture_tutorial_checkbox_bg"
|
||||
app:layout_constraintEnd_toEndOf="@id/gesture_tutorial_checkbox_bg"
|
||||
app:layout_constraintStart_toStartOf="@id/gesture_tutorial_checkbox_bg"
|
||||
app:layout_constraintTop_toTopOf="@id/gesture_tutorial_checkbox_bg" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/gesture_tutorial_fragment_action_button"
|
||||
style="@style/TextAppearance.GestureTutorial.ButtonLabel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="48dp"
|
||||
android:background="@drawable/gesture_tutorial_action_button_background"
|
||||
android:stateListAnimator="@null"
|
||||
android:text="@string/gesture_tutorial_action_button_label"
|
||||
android:visibility="gone"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/gesture_tutorial_checkbox_bg" />
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/checkmark_animation" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -41,4 +41,10 @@
|
||||
<!-- Transient taskbar -->
|
||||
<dimen name="transient_taskbar_size">76dp</dimen>
|
||||
<dimen name="transient_taskbar_icon_size">52dp</dimen>
|
||||
|
||||
<!-- Taskbar swipe up thresholds -->
|
||||
<dimen name="taskbar_nav_threshold">30dp</dimen>
|
||||
<dimen name="taskbar_app_window_threshold">100dp</dimen>
|
||||
<dimen name="taskbar_home_overview_threshold">180dp</dimen>
|
||||
<dimen name="taskbar_catch_up_threshold">300dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
<!-- Redesigned gesture navigation tutorial -->
|
||||
<color name="gesture_home_tutorial_background">#FFB399</color>
|
||||
<color name="gesture_home_tutorial_swipe_up_rect">#3857C7</color>
|
||||
<color name="gesture_back_tutorial_background">#F3A5B9</color>
|
||||
<color name="gesture_back_tutorial_swipe_rect">#217500</color>
|
||||
<color name="gesture_back_tutorial_exiting_app">#F3A5B9</color>
|
||||
<color name="gesture_back_tutorial_background">#3857C7</color>
|
||||
<color name="gesture_overview_tutorial_swipe_rect">#7E44AD</color>
|
||||
|
||||
<!-- Mock hotseat -->
|
||||
|
||||
@@ -121,6 +121,8 @@
|
||||
<dimen name="gesture_tutorial_multi_row_task_view_spacing">72dp</dimen>
|
||||
<dimen name="gesture_tutorial_small_task_view_corner_radius">18dp</dimen>
|
||||
<dimen name="gesture_tutorial_mock_taskbar_height">80dp</dimen>
|
||||
<dimen name="gesture_tutorial_back_gesture_exiting_app_margin">8dp</dimen>
|
||||
<dimen name="gesture_tutorial_back_gesture_end_corner_radius">36dp</dimen>
|
||||
|
||||
<!-- Gesture Tutorial mock conversations -->
|
||||
<dimen name="gesture_tutorial_message_icon_size">44dp</dimen>
|
||||
@@ -301,10 +303,10 @@
|
||||
<!-- An additional touch slop to prevent x-axis movement during the swipe up to show taskbar -->
|
||||
<dimen name="transient_taskbar_clamped_offset_bound">16dp</dimen>
|
||||
<!-- Taskbar swipe up thresholds -->
|
||||
<dimen name="taskbar_nav_threshold">30dp</dimen>
|
||||
<dimen name="taskbar_app_window_threshold">100dp</dimen>
|
||||
<dimen name="taskbar_home_overview_threshold">180dp</dimen>
|
||||
<dimen name="taskbar_catch_up_threshold">300dp</dimen>
|
||||
<dimen name="taskbar_nav_threshold">40dp</dimen>
|
||||
<dimen name="taskbar_app_window_threshold">88dp</dimen>
|
||||
<dimen name="taskbar_home_overview_threshold">156dp</dimen>
|
||||
<dimen name="taskbar_catch_up_threshold">264dp</dimen>
|
||||
|
||||
<!-- Taskbar 3 button spacing -->
|
||||
<dimen name="taskbar_button_space_inbetween">24dp</dimen>
|
||||
|
||||
@@ -117,6 +117,8 @@
|
||||
<string name="back_gesture_intro_subtitle">To go back to the last screen, swipe from the left or right edge to the middle of the screen.</string>
|
||||
<!-- Introduction subtitle for the Back gesture tutorial that will be spoken by screen readers. [CHAR LIMIT=200] -->
|
||||
<string name="back_gesture_spoken_intro_subtitle">To go back to the last screen, swipe with 2 fingers from the left or right edge to the middle of the screen.</string>
|
||||
<!-- Title of the gesture tutorial section educating users on how to go back to the previous screen. [CHAR LIMIT=100] -->
|
||||
<string name="back_gesture_tutorial_title">Go back</string>
|
||||
|
||||
<string name="home_gesture_feedback_swipe_too_far_from_edge">Make sure you swipe up from the bottom edge of the screen.</string>
|
||||
<!-- Feedback shown during interactive parts of Home gesture tutorial when the Overview gesture is detected. [CHAR LIMIT=100] -->
|
||||
|
||||
@@ -230,4 +230,9 @@
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
<item name="lineHeight">20sp</item>
|
||||
</style>
|
||||
|
||||
<style name="GestureTutorialActivity"
|
||||
parent="@style/AppTheme">
|
||||
<item name="background">@android:color/transparent</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
@@ -137,6 +137,8 @@ import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.TaskViewUtils;
|
||||
import com.android.quickstep.util.MultiValueUpdateListener;
|
||||
import com.android.quickstep.util.RectFSpringAnim;
|
||||
import com.android.quickstep.util.RectFSpringAnim.DefaultSpringConfig;
|
||||
import com.android.quickstep.util.RectFSpringAnim.TaskbarHotseatSpringConfig;
|
||||
import com.android.quickstep.util.RemoteAnimationProvider;
|
||||
import com.android.quickstep.util.StaggeredWorkspaceAnim;
|
||||
import com.android.quickstep.util.SurfaceTransaction;
|
||||
@@ -795,7 +797,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
|
||||
if (initOnly) {
|
||||
// For the init pass, we want full alpha since the window is not yet ready.
|
||||
floatingView.update(1f, 255, floatingIconBounds, percent, 0f,
|
||||
floatingView.update(1f, floatingIconBounds, percent, 0f,
|
||||
mWindowRadius.value * scale, true /* isOpening */);
|
||||
return;
|
||||
}
|
||||
@@ -823,7 +825,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
matrix.postTranslate(windowTransX0, windowTransY0);
|
||||
}
|
||||
|
||||
floatingView.update(mIconAlpha.value, 255, floatingIconBounds, percent, 0f,
|
||||
floatingView.update(mIconAlpha.value, floatingIconBounds, percent, 0f,
|
||||
mWindowRadius.value * scale, true /* isOpening */);
|
||||
builder.setMatrix(matrix)
|
||||
.setWindowCrop(crop)
|
||||
@@ -1349,6 +1351,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
}
|
||||
|
||||
// Get floating view and target rect.
|
||||
boolean isInHotseat = false;
|
||||
if (launcherView instanceof LauncherAppWidgetHostView) {
|
||||
Size windowSize = new Size(mDeviceProfile.availableWidthPx,
|
||||
mDeviceProfile.availableHeightPx);
|
||||
@@ -1364,12 +1367,17 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
? null
|
||||
: mLauncher.getTaskbarUIController().findMatchingView(launcherView),
|
||||
true /* hideOriginal */, targetRect, false /* isOpening */);
|
||||
isInHotseat = launcherView.getTag() instanceof ItemInfo
|
||||
&& ((ItemInfo) launcherView.getTag()).isInHotseat();
|
||||
} else {
|
||||
targetRect.set(getDefaultWindowTargetRect());
|
||||
}
|
||||
|
||||
RectFSpringAnim anim = new RectFSpringAnim(closingWindowStartRect, targetRect, mLauncher,
|
||||
mDeviceProfile);
|
||||
boolean useTaskbarHotseatParams = mDeviceProfile.isTaskbarPresent && isInHotseat;
|
||||
RectFSpringAnim anim = new RectFSpringAnim(useTaskbarHotseatParams
|
||||
? new TaskbarHotseatSpringConfig(mLauncher, closingWindowStartRect, targetRect)
|
||||
: new DefaultSpringConfig(mLauncher, mDeviceProfile, closingWindowStartRect,
|
||||
targetRect));
|
||||
|
||||
// Hook up floating views to the closing window animators.
|
||||
final int rotationChange = getRotationChange(targets);
|
||||
@@ -1388,8 +1396,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener
|
||||
windowTargetBounds, startWindowCornerRadius) {
|
||||
@Override
|
||||
public void onUpdate(RectF currentRectF, float progress) {
|
||||
finalFloatingIconView.update(1f, 255 /* fgAlpha */, currentRectF, progress,
|
||||
windowAlphaThreshold, getCornerRadius(progress), false);
|
||||
finalFloatingIconView.update(1f, currentRectF, progress, windowAlphaThreshold,
|
||||
getCornerRadius(progress), false);
|
||||
|
||||
super.onUpdate(currentRectF, progress);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,6 @@ import com.android.launcher3.anim.AnimatorListeners;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.launcher3.util.MultiPropertyFactory.MultiProperty;
|
||||
import com.android.launcher3.util.window.RefreshRateTracker;
|
||||
import com.android.quickstep.RecentsAnimationCallbacks;
|
||||
import com.android.quickstep.RecentsAnimationController;
|
||||
import com.android.quickstep.views.RecentsView;
|
||||
@@ -67,6 +66,10 @@ import java.util.StringJoiner;
|
||||
/** Equivalent to an int with all 1s for binary operation purposes */
|
||||
private static final int FLAGS_ALL = ~0;
|
||||
|
||||
private static final float TASKBAR_BG_ALPHA_LAUNCHER_NOT_ALIGNED_DELAY_MULT = 0.33f;
|
||||
private static final float TASKBAR_BG_ALPHA_NOT_LAUNCHER_NOT_ALIGNED_DELAY_MULT = 0.33f;
|
||||
private static final float TASKBAR_BG_ALPHA_LAUNCHER_IS_ALIGNED_DURATION_MULT = 0.25f;
|
||||
|
||||
private final AnimatedFloat mIconAlignment =
|
||||
new AnimatedFloat(this::onIconAlignmentRatioChanged);
|
||||
|
||||
@@ -274,7 +277,8 @@ import java.util.StringJoiner;
|
||||
|
||||
private Animator onStateChangeApplied(int changedFlags, long duration, boolean start) {
|
||||
final boolean goingToLauncher = isInLauncher();
|
||||
final float toAlignment = isIconAlignedWithHotseat() ? 1 : 0;
|
||||
final boolean isIconAlignedWithHotseat = isIconAlignedWithHotseat();
|
||||
final float toAlignment = isIconAlignedWithHotseat ? 1 : 0;
|
||||
boolean handleOpenFloatingViews = false;
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onStateChangeApplied - mState: " + getStateString(mState)
|
||||
@@ -343,15 +347,29 @@ import java.util.StringJoiner;
|
||||
+ " -> " + backgroundAlpha + ": " + duration);
|
||||
}
|
||||
|
||||
boolean goingToLauncherIconNotAligned = goingToLauncher && !isIconAlignedWithHotseat;
|
||||
boolean notGoingToLauncherIconNotAligned = !goingToLauncher
|
||||
&& !isIconAlignedWithHotseat;
|
||||
boolean goingToLauncherIconIsAligned = goingToLauncher && isIconAlignedWithHotseat;
|
||||
|
||||
float startDelay = 0;
|
||||
// We want to delay the background from fading in so that the icons have time to move
|
||||
// into the bounds of the background before it appears.
|
||||
if (goingToLauncherIconNotAligned) {
|
||||
startDelay = duration * TASKBAR_BG_ALPHA_LAUNCHER_NOT_ALIGNED_DELAY_MULT;
|
||||
} else if (notGoingToLauncherIconNotAligned) {
|
||||
startDelay = duration * TASKBAR_BG_ALPHA_NOT_LAUNCHER_NOT_ALIGNED_DELAY_MULT;
|
||||
}
|
||||
float newDuration = duration - startDelay;
|
||||
if (goingToLauncherIconIsAligned) {
|
||||
// Make the background fade out faster so that it is gone by the time the
|
||||
// icons move outside of the bounds of the background.
|
||||
newDuration = duration * TASKBAR_BG_ALPHA_LAUNCHER_IS_ALIGNED_DURATION_MULT;
|
||||
}
|
||||
Animator taskbarBackgroundAlpha = mTaskbarBackgroundAlpha
|
||||
.animateToValue(backgroundAlpha)
|
||||
.setDuration(duration);
|
||||
// Add a single frame delay to the taskbar bg to avoid too many moving parts during the
|
||||
// app launch animation.
|
||||
taskbarBackgroundAlpha.setStartDelay(
|
||||
(hasAnyFlag(changedFlags, FLAG_RESUMED) && !goingToLauncher)
|
||||
? RefreshRateTracker.getSingleFrameMs(mLauncher)
|
||||
: 0);
|
||||
.setDuration((long) newDuration);
|
||||
taskbarBackgroundAlpha.setStartDelay((long) startDelay);
|
||||
animatorSet.play(taskbarBackgroundAlpha);
|
||||
}
|
||||
|
||||
|
||||
@@ -90,9 +90,6 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
public static final int ALPHA_INDEX_SMALL_SCREEN = 6;
|
||||
private static final int NUM_ALPHA_CHANNELS = 7;
|
||||
|
||||
// This allows the icons on the edge to stay within the taskbar background bounds.
|
||||
private static final float ICON_REVEAL_X_DURATION_MULTIPLIER = 0.8f;
|
||||
|
||||
private static final float TASKBAR_DARK_THEME_ICONS_BACKGROUND_LUMINANCE = 0.30f;
|
||||
|
||||
private final TaskbarActivityContext mActivity;
|
||||
@@ -134,6 +131,8 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
private final DeviceProfile.OnDeviceProfileChangeListener mDeviceProfileChangeListener =
|
||||
dp -> commitRunningAppsToUI();
|
||||
|
||||
private final boolean mIsRtl;
|
||||
|
||||
public TaskbarViewController(TaskbarActivityContext activity, TaskbarView taskbarView) {
|
||||
mActivity = activity;
|
||||
mTaskbarView = taskbarView;
|
||||
@@ -180,6 +179,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
}, VERTICAL);
|
||||
mSwipeDownDetector.setDetectableScrollConditions(DIRECTION_NEGATIVE, false);
|
||||
}
|
||||
mIsRtl = Utilities.isRtl(mTaskbarView.getResources());
|
||||
}
|
||||
|
||||
public void init(TaskbarControllers controllers) {
|
||||
@@ -309,18 +309,34 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
));
|
||||
}
|
||||
|
||||
private ValueAnimator createRevealAnimForView(View view, boolean isStashed) {
|
||||
private ValueAnimator createRevealAnimForView(View view, boolean isStashed, float newWidth,
|
||||
boolean shouldStartAlign) {
|
||||
Rect viewBounds = new Rect(0, 0, view.getWidth(), view.getHeight());
|
||||
int centerY = viewBounds.centerY();
|
||||
int halfHandleHeight = mStashedHandleHeight / 2;
|
||||
final int top = centerY - halfHandleHeight;
|
||||
final int bottom = centerY + halfHandleHeight;
|
||||
|
||||
Rect stashedRect = new Rect(viewBounds.left,
|
||||
centerY - halfHandleHeight,
|
||||
viewBounds.right,
|
||||
centerY + halfHandleHeight);
|
||||
final int left;
|
||||
final int right;
|
||||
if (shouldStartAlign) {
|
||||
if (mIsRtl) {
|
||||
right = viewBounds.right;
|
||||
left = (int) (right - newWidth);
|
||||
} else {
|
||||
left = viewBounds.left;
|
||||
right = (int) (left + newWidth);
|
||||
}
|
||||
} else {
|
||||
int widthDelta = (int) ((viewBounds.width() - newWidth) / 2);
|
||||
|
||||
left = viewBounds.left + widthDelta;
|
||||
right = viewBounds.right - widthDelta;
|
||||
}
|
||||
|
||||
Rect stashedRect = new Rect(left, top, right, bottom);
|
||||
float radius = 0;
|
||||
float stashedRadius = viewBounds.width() / 2f;
|
||||
float stashedRadius = stashedRect.width() / 2f;
|
||||
|
||||
return new RoundedRectRevealOutlineProvider(radius, stashedRadius, viewBounds, stashedRect)
|
||||
.createRevealAnimator(view, !isStashed, 0);
|
||||
@@ -342,44 +358,36 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
Rect stashedBounds = new Rect();
|
||||
mControllers.stashedHandleViewController.getStashedHandleBounds(stashedBounds);
|
||||
|
||||
boolean isQsbInline = mActivity.getDeviceProfile().isQsbInline;
|
||||
int numIcons = mTaskbarView.getChildCount() - (isQsbInline ? 1 : 0);
|
||||
// We do not actually modify the width of the icons, but we will use this width to position
|
||||
// the children to overlay the nav handle.
|
||||
float virtualChildWidth = stashedBounds.width() / (float) numIcons;
|
||||
int numIcons = mTaskbarView.getChildCount();
|
||||
float newChildWidth = stashedBounds.width() / (float) numIcons;
|
||||
|
||||
// All children move the same y-amount since they will be cropped to the same centerY.
|
||||
float croppedTransY = mTaskbarView.getIconTouchSize() - stashedBounds.height();
|
||||
|
||||
boolean isRtl = Utilities.isRtl(mTaskbarView.getResources());
|
||||
for (int i = mTaskbarView.getChildCount() - 1; i >= 0; i--) {
|
||||
View child = mTaskbarView.getChildAt(i);
|
||||
boolean isQsb = child == mTaskbarView.getQsb();
|
||||
|
||||
// Crop the icons to/from the nav handle shape.
|
||||
reveal.play(createRevealAnimForView(child, isStashed).setDuration(duration));
|
||||
reveal.play(createRevealAnimForView(child, isStashed, newChildWidth, isQsb)
|
||||
.setDuration(duration));
|
||||
|
||||
// Translate the icons to/from their locations as the "nav handle."
|
||||
// We look at 'left' and 'right' values to ensure that the children stay within the
|
||||
// bounds of the stashed handle.
|
||||
|
||||
// All of the Taskbar icons will overlap the entirety of the stashed handle
|
||||
// And the QSB, if inline, will overlap part of stashed handle as well.
|
||||
int positionInHandle = (isQsbInline && !isQsb)
|
||||
? i + (isRtl ? 1 : -1)
|
||||
: i;
|
||||
float currentPosition = isQsb ? child.getX() : child.getLeft();
|
||||
float newPosition = stashedBounds.left + (virtualChildWidth * positionInHandle);
|
||||
float newPosition = stashedBounds.left + (newChildWidth * i);
|
||||
final float croppedTransX;
|
||||
// We look at 'left' and 'right' values to ensure that the children stay within the
|
||||
// bounds of the stashed handle since the new width only occurs at the end of the anim.
|
||||
if (currentPosition > newPosition) {
|
||||
float newRight = stashedBounds.right - (virtualChildWidth
|
||||
* (numIcons - 1 - positionInHandle));
|
||||
float newRight = stashedBounds.right - (newChildWidth
|
||||
* (numIcons - 1 - i));
|
||||
croppedTransX = -(currentPosition + child.getWidth() - newRight);
|
||||
} else {
|
||||
croppedTransX = newPosition - currentPosition;
|
||||
}
|
||||
|
||||
long transXDuration = (long) (duration * ICON_REVEAL_X_DURATION_MULTIPLIER);
|
||||
float[] transX = isStashed
|
||||
? new float[] {croppedTransX}
|
||||
: new float[] {croppedTransX, 0};
|
||||
@@ -392,14 +400,14 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
|
||||
reveal.play(ObjectAnimator.ofFloat(mtd.getTranslationX(INDEX_TASKBAR_REVEAL_ANIM),
|
||||
MULTI_PROPERTY_VALUE, transX)
|
||||
.setDuration(transXDuration));
|
||||
.setDuration(duration));
|
||||
reveal.play(ObjectAnimator.ofFloat(mtd.getTranslationY(INDEX_TASKBAR_REVEAL_ANIM),
|
||||
MULTI_PROPERTY_VALUE, transY));
|
||||
as.addListener(forEndCallback(() ->
|
||||
mtd.setTranslation(INDEX_TASKBAR_REVEAL_ANIM, 0, 0)));
|
||||
} else {
|
||||
reveal.play(ObjectAnimator.ofFloat(child, VIEW_TRANSLATE_X, transX)
|
||||
.setDuration(transXDuration));
|
||||
.setDuration(duration));
|
||||
reveal.play(ObjectAnimator.ofFloat(child, VIEW_TRANSLATE_Y, transY));
|
||||
as.addListener(forEndCallback(() -> {
|
||||
child.setTranslationX(0);
|
||||
|
||||
@@ -38,6 +38,7 @@ import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.launcher3.util.ObjectWrapper;
|
||||
@@ -122,6 +123,12 @@ public class LauncherSwipeHandlerV2 extends
|
||||
return workspaceView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInHotseat() {
|
||||
return workspaceView.getTag() instanceof ItemInfo
|
||||
&& ((ItemInfo) workspaceView.getTag()).isInHotseat();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public RectF getWindowTargetRect() {
|
||||
@@ -139,8 +146,8 @@ public class LauncherSwipeHandlerV2 extends
|
||||
@Override
|
||||
public void update(RectF currentRect, float progress, float radius) {
|
||||
super.update(currentRect, progress, radius);
|
||||
floatingIconView.update(1f /* alpha */, 255 /* fgAlpha */, currentRect, progress,
|
||||
windowAlphaThreshold, radius, false);
|
||||
floatingIconView.update(1f /* alpha */, currentRect, progress, windowAlphaThreshold,
|
||||
radius, false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.util.RectFSpringAnim;
|
||||
import com.android.quickstep.util.RectFSpringAnim.DefaultSpringConfig;
|
||||
import com.android.quickstep.util.RectFSpringAnim.TaskbarHotseatSpringConfig;
|
||||
import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
|
||||
import com.android.quickstep.util.TaskViewSimulator;
|
||||
import com.android.quickstep.util.TransformParams;
|
||||
@@ -157,6 +159,13 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
protected abstract class HomeAnimationFactory {
|
||||
protected float mSwipeVelocity;
|
||||
|
||||
/**
|
||||
* Returns true if we know the home animation involves an item in the hotseat.
|
||||
*/
|
||||
public boolean isInHotseat() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public @NonNull RectF getWindowTargetRect() {
|
||||
PagedOrientationHandler orientationHandler = getOrientationHandler();
|
||||
DeviceProfile dp = mDp;
|
||||
@@ -288,7 +297,11 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
homeToWindowPositionMap.invert(windowToHomePositionMap);
|
||||
windowToHomePositionMap.mapRect(startRect);
|
||||
|
||||
RectFSpringAnim anim = new RectFSpringAnim(startRect, targetRect, mContext, mDp);
|
||||
boolean useTaskbarHotseatParams = mDp.isTaskbarPresent
|
||||
&& homeAnimationFactory.isInHotseat();
|
||||
RectFSpringAnim anim = new RectFSpringAnim(useTaskbarHotseatParams
|
||||
? new TaskbarHotseatSpringConfig(mContext, startRect, targetRect)
|
||||
: new DefaultSpringConfig(mContext, mDp, startRect, targetRect));
|
||||
homeAnimationFactory.setAnimation(anim);
|
||||
|
||||
SpringAnimationRunner runner = new SpringAnimationRunner(
|
||||
|
||||
+71
-10
@@ -15,18 +15,24 @@
|
||||
*/
|
||||
package com.android.quickstep.interaction;
|
||||
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
|
||||
import static com.android.quickstep.interaction.TutorialController.TutorialType.BACK_NAVIGATION;
|
||||
import static com.android.quickstep.interaction.TutorialController.TutorialType.BACK_NAVIGATION_COMPLETE;
|
||||
|
||||
import android.annotation.LayoutRes;
|
||||
import android.graphics.PointF;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureResult;
|
||||
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureResult;
|
||||
|
||||
/** A {@link TutorialController} for the Back tutorial. */
|
||||
final class BackGestureTutorialController extends TutorialController {
|
||||
private static final float Y_TRANSLATION_SMOOTHENING_FACTOR = .2f;
|
||||
private static final float EXITING_APP_MIN_SIZE_PERCENTAGE = .8f;
|
||||
|
||||
BackGestureTutorialController(BackGestureTutorialFragment fragment, TutorialType tutorialType) {
|
||||
super(fragment, tutorialType);
|
||||
@@ -34,7 +40,9 @@ final class BackGestureTutorialController extends TutorialController {
|
||||
|
||||
@Override
|
||||
public int getIntroductionTitle() {
|
||||
return R.string.back_gesture_intro_title;
|
||||
return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
|
||||
? R.string.back_gesture_tutorial_title
|
||||
: R.string.back_gesture_intro_title;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,27 +69,32 @@ final class BackGestureTutorialController extends TutorialController {
|
||||
|
||||
@Override
|
||||
protected int getGestureLottieAnimationId() {
|
||||
// TODO(b/253521922): Change to correct LottieAnimationView
|
||||
return R.raw.home_gesture_tutorial_animation;
|
||||
return mTutorialFragment.isLargeScreen()
|
||||
? R.raw.back_gesture_tutorial_tablet_animation
|
||||
: R.raw.back_gesture_tutorial_animation;
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
int getMockAppTaskCurrentPageLayoutResId() {
|
||||
return mTutorialFragment.isLargeScreen()
|
||||
? R.layout.gesture_tutorial_tablet_mock_conversation
|
||||
: R.layout.gesture_tutorial_mock_conversation;
|
||||
return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
|
||||
? R.layout.back_gesture_tutorial_background
|
||||
: mTutorialFragment.isLargeScreen()
|
||||
? R.layout.gesture_tutorial_tablet_mock_conversation
|
||||
: R.layout.gesture_tutorial_mock_conversation;
|
||||
}
|
||||
|
||||
@LayoutRes
|
||||
int getMockAppTaskPreviousPageLayoutResId() {
|
||||
return mTutorialFragment.isLargeScreen()
|
||||
? R.layout.gesture_tutorial_tablet_mock_conversation_list
|
||||
: R.layout.gesture_tutorial_mock_conversation_list;
|
||||
return ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()
|
||||
? R.layout.back_gesture_tutorial_background
|
||||
: mTutorialFragment.isLargeScreen()
|
||||
? R.layout.gesture_tutorial_tablet_mock_conversation_list
|
||||
: R.layout.gesture_tutorial_mock_conversation_list;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSwipeActionColorResId() {
|
||||
return R.color.gesture_back_tutorial_swipe_rect;
|
||||
return R.color.gesture_back_tutorial_background;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,11 +115,59 @@ final class BackGestureTutorialController extends TutorialController {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackGestureProgress(float diffx, float diffy, boolean isLeftGesture) {
|
||||
if (isGestureCompleted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
float normalizedSwipeProgress = Math.abs(diffx / mScreenWidth);
|
||||
float smoothedExitingAppScale = Utilities.mapBoundToRange(
|
||||
normalizedSwipeProgress,
|
||||
/* lowerBound = */ 0f,
|
||||
/* upperBound = */ 1f,
|
||||
/* toMin = */ 1f,
|
||||
/* toMax = */ EXITING_APP_MIN_SIZE_PERCENTAGE,
|
||||
Interpolators.DEACCEL);
|
||||
|
||||
// shrink the exiting app as we progress through the back gesture
|
||||
mExitingAppView.setPivotX(isLeftGesture ? mScreenWidth : 0);
|
||||
mExitingAppView.setPivotY(mScreenHeight / 2f);
|
||||
mExitingAppView.setScaleX(smoothedExitingAppScale);
|
||||
mExitingAppView.setScaleY(smoothedExitingAppScale);
|
||||
mExitingAppView.setTranslationY(diffy * Y_TRANSLATION_SMOOTHENING_FACTOR);
|
||||
mExitingAppView.setTranslationX(Utilities.mapBoundToRange(
|
||||
normalizedSwipeProgress,
|
||||
/* lowerBound = */ 0f,
|
||||
/* upperBound = */ 1f,
|
||||
/* toMin = */ 0,
|
||||
/* toMax = */ mExitingAppMargin,
|
||||
Interpolators.DEACCEL)
|
||||
* (isLeftGesture ? -1 : 1));
|
||||
|
||||
// round the corners of the exiting app as we progress through the back gesture
|
||||
mExitingAppRadius = (int) Utilities.mapBoundToRange(
|
||||
normalizedSwipeProgress,
|
||||
/* lowerBound = */ 0f,
|
||||
/* upperBound = */ 1f,
|
||||
/* toMin = */ mExitingAppStartingCornerRadius,
|
||||
/* toMax = */ mExitingAppEndingCornerRadius,
|
||||
Interpolators.EMPHASIZED_DECELERATE);
|
||||
mExitingAppView.invalidateOutline();
|
||||
}
|
||||
|
||||
private void handleBackAttempt(BackGestureResult result) {
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
resetViewsForBackGesture();
|
||||
}
|
||||
|
||||
switch (result) {
|
||||
case BACK_COMPLETED_FROM_LEFT:
|
||||
case BACK_COMPLETED_FROM_RIGHT:
|
||||
mTutorialFragment.releaseFeedbackAnimation();
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
mExitingAppView.setVisibility(View.GONE);
|
||||
}
|
||||
updateFakeAppTaskViewLayout(getMockAppTaskPreviousPageLayoutResId());
|
||||
showSuccessFeedback();
|
||||
break;
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.android.quickstep.interaction;
|
||||
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_NEW_GESTURE_NAV_TUTORIAL;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Point;
|
||||
@@ -29,8 +31,8 @@ import android.view.ViewGroup.LayoutParams;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.testing.shared.ResourceUtils;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.testing.shared.ResourceUtils;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
|
||||
/**
|
||||
@@ -207,7 +209,11 @@ public class EdgeBackGestureHandler implements OnTouchListener {
|
||||
mThresholdCrossed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
mGestureCallback.onBackGestureProgress(ev.getX() - mDownPoint.x,
|
||||
ev.getY() - mDownPoint.y, mEdgeBackPanel.getIsLeftPanel());
|
||||
}
|
||||
|
||||
// forward touch
|
||||
@@ -242,5 +248,8 @@ public class EdgeBackGestureHandler implements OnTouchListener {
|
||||
interface BackGestureAttemptCallback {
|
||||
/** Called whenever any touch is completed. */
|
||||
void onBackGestureAttempted(BackGestureResult result);
|
||||
|
||||
/** Called when the back gesture is recognized and is in progress. */
|
||||
default void onBackGestureProgress(float diffx, float diffy, boolean isLeftGesture) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,9 @@ final class HomeGestureTutorialController extends SwipeUpGestureTutorialControll
|
||||
|
||||
@Override
|
||||
protected int getGestureLottieAnimationId() {
|
||||
return R.raw.home_gesture_tutorial_animation;
|
||||
return mTutorialFragment.isLargeScreen()
|
||||
? R.raw.home_gesture_tutorial_tablet_animation
|
||||
: R.raw.home_gesture_tutorial_animation;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -354,7 +354,7 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||
mFakeIconView.setVisibility(View.VISIBLE);
|
||||
mFakeIconView.update(rect, progress,
|
||||
1f - SHAPE_PROGRESS_DURATION /* shapeProgressStart */,
|
||||
radius, 255,
|
||||
radius,
|
||||
false, /* isOpening */
|
||||
mFakeIconView, mDp);
|
||||
mFakeIconView.setAlpha(1);
|
||||
|
||||
@@ -30,12 +30,15 @@ import android.annotation.ColorRes;
|
||||
import android.annotation.RawRes;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Outline;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.AnimatedVectorDrawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewOutlineProvider;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
@@ -59,6 +62,7 @@ import com.android.launcher3.anim.AnimatorListeners;
|
||||
import com.android.launcher3.views.ClipIconView;
|
||||
import com.android.quickstep.interaction.EdgeBackGestureHandler.BackGestureAttemptCallback;
|
||||
import com.android.quickstep.interaction.NavBarGestureHandler.NavBarGestureAttemptCallback;
|
||||
import com.android.systemui.shared.system.QuickStepContract;
|
||||
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
|
||||
@@ -81,6 +85,11 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
private static final int GESTURE_ANIMATION_DELAY_MS = 1500;
|
||||
private static final int ADVANCE_TUTORIAL_TIMEOUT_MS = 2000;
|
||||
private static final long GESTURE_ANIMATION_PAUSE_DURATION_MILLIS = 1000;
|
||||
protected float mExitingAppEndingCornerRadius;
|
||||
protected float mExitingAppStartingCornerRadius;
|
||||
protected int mScreenHeight;
|
||||
protected float mScreenWidth;
|
||||
protected float mExitingAppMargin;
|
||||
|
||||
final TutorialFragment mTutorialFragment;
|
||||
TutorialType mTutorialType;
|
||||
@@ -103,10 +112,14 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
final RippleDrawable mRippleDrawable;
|
||||
final TutorialStepIndicator mTutorialStepView;
|
||||
final ImageView mFingerDotView;
|
||||
private final Rect mExitingAppRect = new Rect();
|
||||
protected View mExitingAppView;
|
||||
protected int mExitingAppRadius;
|
||||
private final AlertDialog mSkipTutorialDialog;
|
||||
|
||||
private boolean mGestureCompleted = false;
|
||||
private LottieAnimationView mAnimatedGestureDemonstration;
|
||||
private LottieAnimationView mCheckmarkAnimation;
|
||||
private RelativeLayout mFullGestureDemonstration;
|
||||
|
||||
// These runnables should be used when posting callbacks to their views and cleared from their
|
||||
@@ -147,13 +160,28 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
mSkipTutorialDialog = createSkipTutorialDialog();
|
||||
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
mAnimatedGestureDemonstration = mTutorialFragment.getRootView().findViewById(
|
||||
mFullGestureDemonstration = rootView.findViewById(R.id.full_gesture_demonstration);
|
||||
mCheckmarkAnimation = rootView.findViewById(R.id.checkmark_animation);
|
||||
mAnimatedGestureDemonstration = rootView.findViewById(
|
||||
R.id.gesture_demonstration_animations);
|
||||
mFullGestureDemonstration = mTutorialFragment.getRootView().findViewById(
|
||||
R.id.full_gesture_demonstration);
|
||||
mExitingAppView = rootView.findViewById(R.id.exiting_app_back);
|
||||
mScreenWidth = mTutorialFragment.getDeviceProfile().widthPx;
|
||||
mScreenHeight = mTutorialFragment.getDeviceProfile().heightPx;
|
||||
mExitingAppMargin = mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.gesture_tutorial_back_gesture_exiting_app_margin);
|
||||
mExitingAppStartingCornerRadius = QuickStepContract.getWindowCornerRadius(mContext);
|
||||
mExitingAppEndingCornerRadius = mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.gesture_tutorial_back_gesture_end_corner_radius);
|
||||
|
||||
mFeedbackTitleView.setText(getIntroductionTitle());
|
||||
mFeedbackSubtitleView.setText(getIntroductionSubtitle());
|
||||
mExitingAppView.setClipToOutline(true);
|
||||
mExitingAppView.setOutlineProvider(new ViewOutlineProvider() {
|
||||
@Override
|
||||
public void getOutline(View view, Outline outline) {
|
||||
outline.setRoundRect(mExitingAppRect, mExitingAppRadius);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mTitleViewCallback = () -> mFeedbackTitleView.sendAccessibilityEvent(
|
||||
@@ -373,10 +401,8 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
}
|
||||
|
||||
private void showSuccessPage() {
|
||||
mFeedbackView.findViewById(
|
||||
R.id.gesture_tutorial_checkbox_bg).setVisibility(View.VISIBLE);
|
||||
mFeedbackView.findViewById(
|
||||
R.id.gesture_tutorial_checkbox).setVisibility(View.VISIBLE);
|
||||
mCheckmarkAnimation.setVisibility(View.VISIBLE);
|
||||
mCheckmarkAnimation.playAnimation();
|
||||
mFeedbackTitleView.setTextAppearance(R.style.TextAppearance_GestureTutorial_SuccessTitle);
|
||||
mFeedbackSubtitleView.setTextAppearance(
|
||||
R.style.TextAppearance_GestureTutorial_SuccessSubtitle);
|
||||
@@ -496,7 +522,17 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
updateLayout();
|
||||
|
||||
if (ENABLE_NEW_GESTURE_NAV_TUTORIAL.get()) {
|
||||
startGestureAnimation();
|
||||
mCheckmarkAnimation.setAnimation(mTutorialFragment.isAtFinalStep()
|
||||
? R.raw.checkmark_animation_end
|
||||
: R.raw.checkmark_animation_in_progress);
|
||||
if (!isGestureCompleted()) {
|
||||
mCheckmarkAnimation.setVisibility(GONE);
|
||||
startGestureAnimation();
|
||||
if (mTutorialType == TutorialType.BACK_NAVIGATION) {
|
||||
resetViewsForBackGesture();
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
hideFeedback();
|
||||
hideActionButton();
|
||||
@@ -508,6 +544,23 @@ abstract class TutorialController implements BackGestureAttemptCallback,
|
||||
}
|
||||
}
|
||||
|
||||
protected void resetViewsForBackGesture() {
|
||||
mFakeTaskView.setVisibility(View.VISIBLE);
|
||||
mFakeTaskView.setBackgroundColor(
|
||||
mContext.getColor(R.color.gesture_back_tutorial_background));
|
||||
mExitingAppView.setVisibility(View.VISIBLE);
|
||||
|
||||
// reset the exiting app's dimensions
|
||||
mExitingAppRect.set(0, 0, (int) mScreenWidth, (int) mScreenHeight);
|
||||
mExitingAppRadius = 0;
|
||||
mExitingAppView.resetPivot();
|
||||
mExitingAppView.setScaleX(1f);
|
||||
mExitingAppView.setScaleY(1f);
|
||||
mExitingAppView.setTranslationX(0);
|
||||
mExitingAppView.setTranslationY(0);
|
||||
mExitingAppView.invalidateOutline();
|
||||
}
|
||||
|
||||
private void startGestureAnimation() {
|
||||
mAnimatedGestureDemonstration.setAnimation(getGestureLottieAnimationId());
|
||||
mAnimatedGestureDemonstration.playAnimation();
|
||||
|
||||
@@ -312,7 +312,6 @@ abstract class TutorialFragment extends Fragment implements OnTouchListener {
|
||||
if (mEdgeAnimation != null && mEdgeAnimation.isRunning()) {
|
||||
mEdgeAnimation.stop();
|
||||
}
|
||||
|
||||
mEdgeGestureVideoView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ public class LauncherUnfoldAnimationController {
|
||||
|
||||
// Percentage of the width of the quick search bar that will be reduced
|
||||
// from the both sides of the bar when progress is 0
|
||||
private static final float MAX_WIDTH_INSET_FRACTION = 0.15f;
|
||||
private static final float MAX_WIDTH_INSET_FRACTION = 0.04f;
|
||||
private static final FloatProperty<Workspace<?>> WORKSPACE_SCALE_PROPERTY =
|
||||
WORKSPACE_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_UNFOLD_ANIMATION);
|
||||
private static final FloatProperty<Hotseat> HOTSEAT_SCALE_PROPERTY =
|
||||
@@ -156,6 +156,8 @@ public class LauncherUnfoldAnimationController {
|
||||
|
||||
private class LauncherScaleAnimationListener implements TransitionProgressListener {
|
||||
|
||||
private static final float SCALE_LAUNCHER_FROM = 0.92f;
|
||||
|
||||
@Override
|
||||
public void onTransitionStarted() {
|
||||
mLauncher.getWorkspace().setPivotToScaleWithSelf(mLauncher.getHotseat());
|
||||
@@ -168,7 +170,7 @@ public class LauncherUnfoldAnimationController {
|
||||
|
||||
@Override
|
||||
public void onTransitionProgress(float progress) {
|
||||
setScale(MathUtils.constrainedMap(0.85f, 1, 0, 1, progress));
|
||||
setScale(MathUtils.constrainedMap(SCALE_LAUNCHER_FROM, 1, 0, 1, progress));
|
||||
}
|
||||
|
||||
private void setScale(float value) {
|
||||
|
||||
@@ -128,37 +128,27 @@ public class RectFSpringAnim extends ReleaseCheck {
|
||||
|
||||
@Tracking
|
||||
public final int mTracking;
|
||||
protected final float mStiffnessX;
|
||||
protected final float mStiffnessY;
|
||||
protected final float mDampingX;
|
||||
protected final float mDampingY;
|
||||
protected final float mRectStiffness;
|
||||
|
||||
public RectFSpringAnim(RectF startRect, RectF targetRect, Context context,
|
||||
@Nullable DeviceProfile deviceProfile) {
|
||||
mStartRect = startRect;
|
||||
mTargetRect = targetRect;
|
||||
public RectFSpringAnim(SpringConfig config) {
|
||||
mStartRect = config.startRect;
|
||||
mTargetRect = config.targetRect;
|
||||
mCurrentCenterX = mStartRect.centerX();
|
||||
|
||||
ResourceProvider rp = DynamicResource.provider(context);
|
||||
mMinVisChange = rp.getDimension(R.dimen.swipe_up_fling_min_visible_change);
|
||||
mMaxVelocityPxPerS = (int) rp.getDimension(R.dimen.swipe_up_max_velocity);
|
||||
mMinVisChange = config.minVisChange;
|
||||
mMaxVelocityPxPerS = config.maxVelocityPxPerS;
|
||||
setCanRelease(true);
|
||||
|
||||
if (deviceProfile == null) {
|
||||
mTracking = startRect.bottom < targetRect.bottom
|
||||
? TRACKING_BOTTOM
|
||||
: TRACKING_TOP;
|
||||
} else {
|
||||
int heightPx = deviceProfile.heightPx;
|
||||
Rect padding = deviceProfile.workspacePadding;
|
||||
|
||||
final float topThreshold = heightPx / 3f;
|
||||
final float bottomThreshold = deviceProfile.heightPx - padding.bottom;
|
||||
|
||||
if (targetRect.bottom > bottomThreshold) {
|
||||
mTracking = TRACKING_BOTTOM;
|
||||
} else if (targetRect.top < topThreshold) {
|
||||
mTracking = TRACKING_TOP;
|
||||
} else {
|
||||
mTracking = TRACKING_CENTER;
|
||||
}
|
||||
}
|
||||
mTracking = config.tracking;
|
||||
mStiffnessX = config.stiffnessX;
|
||||
mStiffnessY = config.stiffnessY;
|
||||
mDampingX = config.dampingX;
|
||||
mDampingY = config.dampingY;
|
||||
mRectStiffness = config.rectStiffness;
|
||||
|
||||
mCurrentY = getTrackedYFromRect(mStartRect);
|
||||
}
|
||||
@@ -240,14 +230,15 @@ public class RectFSpringAnim extends ReleaseCheck {
|
||||
float maxXValue = Math.max(startX, endX);
|
||||
|
||||
mRectXAnim = new FlingSpringAnim(this, context, RECT_CENTER_X, startX, endX,
|
||||
dampedXVelocityPxPerS, mMinVisChange, minXValue, maxXValue, onXEndListener);
|
||||
dampedXVelocityPxPerS, mMinVisChange, minXValue, maxXValue, mDampingX, mStiffnessX,
|
||||
onXEndListener);
|
||||
|
||||
float startY = mCurrentY;
|
||||
float endY = getTrackedYFromRect(mTargetRect);
|
||||
float minYValue = Math.min(startY, endY);
|
||||
float maxYValue = Math.max(startY, endY);
|
||||
mRectYAnim = new FlingSpringAnim(this, context, RECT_Y, startY, endY, dampedYVelocityPxPerS,
|
||||
mMinVisChange, minYValue, maxYValue, onYEndListener);
|
||||
mMinVisChange, minYValue, maxYValue, mDampingY, mStiffnessY, onYEndListener);
|
||||
|
||||
float minVisibleChange = Math.abs(1f / mStartRect.height());
|
||||
ResourceProvider rp = DynamicResource.provider(context);
|
||||
@@ -368,4 +359,98 @@ public class RectFSpringAnim extends ReleaseCheck {
|
||||
|
||||
default void onCancel() { }
|
||||
}
|
||||
|
||||
private abstract static class SpringConfig {
|
||||
protected RectF startRect;
|
||||
protected RectF targetRect;
|
||||
protected @Tracking int tracking;
|
||||
protected float stiffnessX;
|
||||
protected float stiffnessY;
|
||||
protected float dampingX;
|
||||
protected float dampingY;
|
||||
protected float rectStiffness;
|
||||
protected float minVisChange;
|
||||
protected int maxVelocityPxPerS;
|
||||
|
||||
private SpringConfig(Context context, RectF start, RectF target) {
|
||||
startRect = start;
|
||||
targetRect = target;
|
||||
|
||||
ResourceProvider rp = DynamicResource.provider(context);
|
||||
minVisChange = rp.getDimension(R.dimen.swipe_up_fling_min_visible_change);
|
||||
maxVelocityPxPerS = (int) rp.getDimension(R.dimen.swipe_up_max_velocity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard spring configuration parameters.
|
||||
*/
|
||||
public static class DefaultSpringConfig extends SpringConfig {
|
||||
|
||||
public DefaultSpringConfig(Context context, DeviceProfile deviceProfile,
|
||||
RectF startRect, RectF targetRect) {
|
||||
super(context, startRect, targetRect);
|
||||
|
||||
ResourceProvider rp = DynamicResource.provider(context);
|
||||
tracking = getDefaultTracking(deviceProfile);
|
||||
stiffnessX = rp.getFloat(R.dimen.swipe_up_rect_xy_stiffness);
|
||||
stiffnessY = rp.getFloat(R.dimen.swipe_up_rect_xy_stiffness);
|
||||
dampingX = rp.getFloat(R.dimen.swipe_up_rect_xy_damping_ratio);
|
||||
dampingY = rp.getFloat(R.dimen.swipe_up_rect_xy_damping_ratio);
|
||||
|
||||
this.startRect = startRect;
|
||||
this.targetRect = targetRect;
|
||||
|
||||
// Increase the stiffness for devices where we want the window size to transform
|
||||
// quicker.
|
||||
boolean shouldUseHigherStiffness = deviceProfile != null
|
||||
&& (deviceProfile.isLandscape || deviceProfile.isTablet);
|
||||
rectStiffness = shouldUseHigherStiffness
|
||||
? rp.getFloat(R.dimen.swipe_up_rect_scale_higher_stiffness)
|
||||
: rp.getFloat(R.dimen.swipe_up_rect_scale_stiffness);
|
||||
}
|
||||
|
||||
private @Tracking int getDefaultTracking(@Nullable DeviceProfile deviceProfile) {
|
||||
@Tracking int tracking;
|
||||
if (deviceProfile == null) {
|
||||
tracking = startRect.bottom < targetRect.bottom
|
||||
? TRACKING_BOTTOM
|
||||
: TRACKING_TOP;
|
||||
} else {
|
||||
int heightPx = deviceProfile.heightPx;
|
||||
Rect padding = deviceProfile.workspacePadding;
|
||||
|
||||
final float topThreshold = heightPx / 3f;
|
||||
final float bottomThreshold = deviceProfile.heightPx - padding.bottom;
|
||||
|
||||
if (targetRect.bottom > bottomThreshold) {
|
||||
tracking = TRACKING_BOTTOM;
|
||||
} else if (targetRect.top < topThreshold) {
|
||||
tracking = TRACKING_TOP;
|
||||
} else {
|
||||
tracking = TRACKING_CENTER;
|
||||
}
|
||||
}
|
||||
return tracking;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Spring configuration parameters for Taskbar/Hotseat items on devices that have a taskbar.
|
||||
*/
|
||||
public static class TaskbarHotseatSpringConfig extends SpringConfig {
|
||||
|
||||
public TaskbarHotseatSpringConfig(Context context, RectF start, RectF target) {
|
||||
super(context, start, target);
|
||||
|
||||
ResourceProvider rp = DynamicResource.provider(context);
|
||||
tracking = TRACKING_CENTER;
|
||||
stiffnessX = rp.getFloat(R.dimen.taskbar_swipe_up_rect_x_stiffness);
|
||||
stiffnessY = rp.getFloat(R.dimen.taskbar_swipe_up_rect_y_stiffness);
|
||||
dampingX = rp.getFloat(R.dimen.taskbar_swipe_up_rect_x_damping);
|
||||
dampingY = rp.getFloat(R.dimen.taskbar_swipe_up_rect_y_damping);
|
||||
rectStiffness = rp.getFloat(R.dimen.taskbar_swipe_up_rect_scale_stiffness);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -124,7 +124,8 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim {
|
||||
int cornerRadius,
|
||||
int shadowRadius,
|
||||
@NonNull View view) {
|
||||
super(startBounds, new RectF(destinationBoundsTransformed), context, null);
|
||||
super(new DefaultSpringConfig(context, null, startBounds,
|
||||
new RectF(destinationBoundsTransformed)));
|
||||
mTaskId = taskId;
|
||||
mActivityInfo = activityInfo;
|
||||
mLeash = leash;
|
||||
|
||||
@@ -164,6 +164,13 @@
|
||||
<item name="swipe_up_rect_xy_damping_ratio" type="dimen" format="float">0.8</item>
|
||||
<item name="swipe_up_rect_xy_stiffness" type="dimen" format="float">200</item>
|
||||
|
||||
<!-- These params are only used for hotseat items on devices that have a taskbar. -->
|
||||
<item name="taskbar_swipe_up_rect_x_stiffness" type="dimen" format="float">350</item>
|
||||
<item name="taskbar_swipe_up_rect_x_damping" type="dimen" format="float">0.9</item>
|
||||
<item name="taskbar_swipe_up_rect_y_stiffness" type="dimen" format="float">200</item>
|
||||
<item name="taskbar_swipe_up_rect_y_damping" type="dimen" format="float">0.78</item>
|
||||
<item name="taskbar_swipe_up_rect_scale_stiffness" type="dimen" format="float">200</item>
|
||||
|
||||
<item name="staggered_damping_ratio" type="dimen" format="float">0.7</item>
|
||||
<item name="staggered_stiffness" type="dimen" format="float">150</item>
|
||||
<dimen name="unlock_staggered_velocity_dp_per_s">2dp</dimen>
|
||||
|
||||
@@ -389,14 +389,6 @@
|
||||
<dimen name="taskbar_button_space_inbetween_phone">0dp</dimen>
|
||||
<dimen name="taskbar_button_margin_split">0dp</dimen>
|
||||
<dimen name="taskbar_button_margin_6_5">0dp</dimen>
|
||||
<!-- Taskbar swipe up thresholds threshold -->
|
||||
<dimen name="taskbar_nav_threshold">0dp</dimen>
|
||||
<dimen name="taskbar_app_window_threshold">0dp</dimen>
|
||||
<dimen name="taskbar_home_overview_threshold">0dp</dimen>
|
||||
<dimen name="taskbar_catch_up_threshold">0dp</dimen>
|
||||
<dimen name="taskbar_nav_threshold_v2">0dp</dimen>
|
||||
<dimen name="taskbar_app_window_threshold_v2">0dp</dimen>
|
||||
<dimen name="taskbar_home_overview_threshold_v2">0dp</dimen>
|
||||
|
||||
<!-- Size of the maximum radius for the enforced rounded rectangles. -->
|
||||
<dimen name="enforced_rounded_corner_max_radius">16dp</dimen>
|
||||
|
||||
@@ -28,6 +28,7 @@ import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVER
|
||||
import static com.android.launcher3.icons.GraphicsUtils.getShapePath;
|
||||
import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE;
|
||||
import static com.android.launcher3.testing.shared.ResourceUtils.pxFromDp;
|
||||
import static com.android.launcher3.testing.shared.ResourceUtils.roundPxValueFromFloat;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
@@ -377,7 +378,7 @@ public class DeviceProfile {
|
||||
|
||||
folderLabelTextScale = res.getFloat(R.dimen.folder_label_text_scale);
|
||||
|
||||
if (inv.folderStyle != INVALID_RESOURCE_HANDLE) {
|
||||
if (isScalableGrid && inv.folderStyle != INVALID_RESOURCE_HANDLE) {
|
||||
TypedArray folderStyle = context.obtainStyledAttributes(inv.folderStyle,
|
||||
R.styleable.FolderStyle);
|
||||
// These are re-set in #updateFolderCellSize if the grid is not scalable
|
||||
@@ -395,7 +396,7 @@ public class DeviceProfile {
|
||||
folderStyle.recycle();
|
||||
} else {
|
||||
folderCellLayoutBorderSpacePx = 0;
|
||||
folderFooterHeightPx = 0;
|
||||
folderFooterHeightPx = res.getDimensionPixelSize(R.dimen.folder_footer_height_default);
|
||||
folderContentPaddingTop = res.getDimensionPixelSize(R.dimen.folder_top_padding_default);
|
||||
}
|
||||
|
||||
@@ -548,6 +549,9 @@ public class DeviceProfile {
|
||||
cellLayoutPadding);
|
||||
updateWorkspacePadding();
|
||||
|
||||
// Folder scaling requires correct workspace paddings
|
||||
updateAvailableFolderCellDimensions(res);
|
||||
|
||||
mMinHotseatIconSpacePx = res.getDimensionPixelSize(R.dimen.min_hotseat_icon_space);
|
||||
mMinHotseatQsbWidthPx = res.getDimensionPixelSize(R.dimen.min_hotseat_qsb_width);
|
||||
mMaxHotseatIconSpacePx = areNavButtonsInline
|
||||
@@ -875,7 +879,6 @@ public class DeviceProfile {
|
||||
extraHeight = Math.max(0, maxHeight - getCellLayoutHeightSpecification());
|
||||
}
|
||||
|
||||
updateAvailableFolderCellDimensions(res);
|
||||
return Math.round(extraHeight);
|
||||
}
|
||||
|
||||
@@ -1064,22 +1067,22 @@ public class DeviceProfile {
|
||||
private void updateAvailableFolderCellDimensions(Resources res) {
|
||||
updateFolderCellSize(1f, res);
|
||||
|
||||
// Don't let the folder get too close to the edges of the screen.
|
||||
int folderMargin = edgeMarginPx * 2;
|
||||
// For usability we can't have the folder use the whole width of the screen
|
||||
Point totalWorkspacePadding = getTotalWorkspacePadding();
|
||||
|
||||
// Check if the icons fit within the available height.
|
||||
// Check if the folder fit within the available height.
|
||||
float contentUsedHeight = folderCellHeightPx * inv.numFolderRows
|
||||
+ ((inv.numFolderRows - 1) * folderCellLayoutBorderSpacePx);
|
||||
int contentMaxHeight = availableHeightPx - totalWorkspacePadding.y - folderFooterHeightPx
|
||||
- folderMargin - folderContentPaddingTop;
|
||||
+ ((inv.numFolderRows - 1) * folderCellLayoutBorderSpacePx)
|
||||
+ folderFooterHeightPx
|
||||
+ folderContentPaddingTop;
|
||||
int contentMaxHeight = availableHeightPx - totalWorkspacePadding.y;
|
||||
float scaleY = contentMaxHeight / contentUsedHeight;
|
||||
|
||||
// Check if the icons fit within the available width.
|
||||
// Check if the folder fit within the available width.
|
||||
float contentUsedWidth = folderCellWidthPx * inv.numFolderColumns
|
||||
+ ((inv.numFolderColumns - 1) * folderCellLayoutBorderSpacePx);
|
||||
int contentMaxWidth = availableWidthPx - totalWorkspacePadding.x - folderMargin
|
||||
- folderContentPaddingLeftRight * 2;
|
||||
+ ((inv.numFolderColumns - 1) * folderCellLayoutBorderSpacePx)
|
||||
+ folderContentPaddingLeftRight * 2;
|
||||
int contentMaxWidth = availableWidthPx - totalWorkspacePadding.x;
|
||||
float scaleX = contentMaxWidth / contentUsedWidth;
|
||||
|
||||
float scale = Math.min(scaleX, scaleY);
|
||||
@@ -1092,17 +1095,25 @@ public class DeviceProfile {
|
||||
float invIconSizeDp = inv.iconSize[mTypeIndex];
|
||||
folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale));
|
||||
folderChildTextSizePx = pxFromSp(inv.iconTextSize[mTypeIndex], mMetrics, scale);
|
||||
folderLabelTextSizePx = Math.max(pxFromSp(MIN_FOLDER_TEXT_SIZE_SP, mMetrics),
|
||||
folderLabelTextSizePx = Math.max(pxFromSp(MIN_FOLDER_TEXT_SIZE_SP, mMetrics, scale),
|
||||
(int) (folderChildTextSizePx * folderLabelTextScale));
|
||||
|
||||
int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx);
|
||||
|
||||
if (isScalableGrid) {
|
||||
if (inv.folderStyle == INVALID_RESOURCE_HANDLE) {
|
||||
folderCellWidthPx = pxFromDp(getCellSize().x, mMetrics, scale);
|
||||
folderCellHeightPx = pxFromDp(getCellSize().y, mMetrics, scale);
|
||||
folderCellWidthPx = roundPxValueFromFloat(getCellSize().x * scale);
|
||||
folderCellHeightPx = roundPxValueFromFloat(getCellSize().y * scale);
|
||||
} else {
|
||||
folderCellWidthPx = roundPxValueFromFloat(folderCellWidthPx * scale);
|
||||
folderCellHeightPx = roundPxValueFromFloat(folderCellHeightPx * scale);
|
||||
}
|
||||
|
||||
folderContentPaddingTop = roundPxValueFromFloat(folderContentPaddingTop * scale);
|
||||
folderCellLayoutBorderSpacePx = roundPxValueFromFloat(
|
||||
folderCellLayoutBorderSpacePx * scale);
|
||||
folderFooterHeightPx = roundPxValueFromFloat(folderFooterHeightPx * scale);
|
||||
|
||||
folderContentPaddingLeftRight = folderCellLayoutBorderSpacePx;
|
||||
} else {
|
||||
int cellPaddingX = (int) (res.getDimensionPixelSize(R.dimen.folder_cell_x_padding)
|
||||
@@ -1112,10 +1123,14 @@ public class DeviceProfile {
|
||||
|
||||
folderCellWidthPx = folderChildIconSizePx + 2 * cellPaddingX;
|
||||
folderCellHeightPx = folderChildIconSizePx + 2 * cellPaddingY + textHeight;
|
||||
folderContentPaddingTop = roundPxValueFromFloat(folderContentPaddingTop * scale);
|
||||
folderContentPaddingLeftRight =
|
||||
res.getDimensionPixelSize(R.dimen.folder_content_padding_left_right);
|
||||
folderFooterHeightPx =
|
||||
res.getDimensionPixelSize(R.dimen.folder_footer_height_default);
|
||||
roundPxValueFromFloat(
|
||||
res.getDimensionPixelSize(R.dimen.folder_footer_height_default)
|
||||
* scale);
|
||||
|
||||
}
|
||||
|
||||
folderChildDrawablePaddingPx = Math.max(0,
|
||||
|
||||
@@ -113,8 +113,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
||||
private float mDownMotionX;
|
||||
private float mDownMotionY;
|
||||
private float mDownMotionPrimary;
|
||||
private float mLastMotion;
|
||||
private float mLastMotionRemainder;
|
||||
private int mLastMotion;
|
||||
private float mTotalMotion;
|
||||
// Used in special cases where the fling checks can be relaxed for an intentional gesture
|
||||
private boolean mAllowEasyFling;
|
||||
@@ -1072,8 +1071,8 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
||||
// Remember location of down touch
|
||||
mDownMotionX = x;
|
||||
mDownMotionY = y;
|
||||
mDownMotionPrimary = mLastMotion = mOrientationHandler.getPrimaryDirection(ev, 0);
|
||||
mLastMotionRemainder = 0;
|
||||
mDownMotionPrimary = mOrientationHandler.getPrimaryDirection(ev, 0);
|
||||
mLastMotion = (int) mDownMotionPrimary;
|
||||
mTotalMotion = 0;
|
||||
mAllowEasyFling = false;
|
||||
mActivePointerId = ev.getPointerId(0);
|
||||
@@ -1155,8 +1154,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
||||
// Scroll if the user moved far enough along the X axis
|
||||
mIsBeingDragged = true;
|
||||
mTotalMotion += Math.abs(mLastMotion - primaryDirection);
|
||||
mLastMotion = primaryDirection;
|
||||
mLastMotionRemainder = 0;
|
||||
mLastMotion = (int) primaryDirection;
|
||||
pageBeginTransition();
|
||||
// Stop listening for things like pinches.
|
||||
requestDisallowInterceptTouchEvent(true);
|
||||
@@ -1265,8 +1263,8 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
||||
// Remember where the motion event started
|
||||
mDownMotionX = ev.getX();
|
||||
mDownMotionY = ev.getY();
|
||||
mDownMotionPrimary = mLastMotion = mOrientationHandler.getPrimaryDirection(ev, 0);
|
||||
mLastMotionRemainder = 0;
|
||||
mDownMotionPrimary = mOrientationHandler.getPrimaryDirection(ev, 0);
|
||||
mLastMotion = (int) mDownMotionPrimary;
|
||||
mTotalMotion = 0;
|
||||
mAllowEasyFling = false;
|
||||
mActivePointerId = ev.getPointerId(0);
|
||||
@@ -1287,28 +1285,29 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
||||
final int pointerIndex = ev.findPointerIndex(mActivePointerId);
|
||||
|
||||
if (pointerIndex == -1) return true;
|
||||
float oldScroll = mOrientationHandler.getPrimaryScroll(this);
|
||||
float dx = ev.getX(pointerIndex);
|
||||
float dy = ev.getY(pointerIndex);
|
||||
int oldScroll = mOrientationHandler.getPrimaryScroll(this);
|
||||
int dx = (int) ev.getX(pointerIndex);
|
||||
int dy = (int) ev.getY(pointerIndex);
|
||||
|
||||
float direction = mOrientationHandler.getPrimaryValue(dx, dy);
|
||||
float delta = mLastMotion + mLastMotionRemainder - direction;
|
||||
int direction = mOrientationHandler.getPrimaryValue(dx, dy);
|
||||
int delta = mLastMotion - direction;
|
||||
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
int size = mOrientationHandler.getPrimaryValue(width, height);
|
||||
|
||||
final float displacement = mOrientationHandler.getSecondaryValue(dx, dy)
|
||||
/ mOrientationHandler.getSecondaryValue(width, height);
|
||||
float size = mOrientationHandler.getPrimaryValue(width, height);
|
||||
float displacement = (width == 0 || height == 0) ? 0
|
||||
: (float) mOrientationHandler.getSecondaryValue(dx, dy)
|
||||
/ mOrientationHandler.getSecondaryValue(width, height);
|
||||
mTotalMotion += Math.abs(delta);
|
||||
|
||||
if (mAllowOverScroll) {
|
||||
float consumed = 0;
|
||||
int consumed = 0;
|
||||
if (delta < 0 && mEdgeGlowRight.getDistance() != 0f) {
|
||||
consumed = size * mEdgeGlowRight.onPullDistance(delta / size, displacement);
|
||||
consumed = Math.round(size *
|
||||
mEdgeGlowRight.onPullDistance(delta / size, displacement));
|
||||
} else if (delta > 0 && mEdgeGlowLeft.getDistance() != 0f) {
|
||||
consumed = -size * mEdgeGlowLeft.onPullDistance(
|
||||
-delta / size, 1 - displacement);
|
||||
consumed = Math.round(-size *
|
||||
mEdgeGlowLeft.onPullDistance(-delta / size, 1 - displacement));
|
||||
}
|
||||
delta -= consumed;
|
||||
}
|
||||
@@ -1318,11 +1317,9 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
||||
// keep the remainder because we are actually testing if we've moved from the last
|
||||
// scrolled position (which is discrete).
|
||||
mLastMotion = direction;
|
||||
int movedDelta = (int) delta;
|
||||
mLastMotionRemainder = delta - movedDelta;
|
||||
|
||||
if (delta != 0) {
|
||||
mOrientationHandler.setPrimary(this, VIEW_SCROLL_BY, movedDelta);
|
||||
mOrientationHandler.setPrimary(this, VIEW_SCROLL_BY, delta);
|
||||
|
||||
if (mAllowOverScroll) {
|
||||
final float pulledToX = oldScroll + delta;
|
||||
@@ -1377,7 +1374,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
||||
* mOrientationHandler.getPrimaryScale(this));
|
||||
boolean isSignificantMove = isSignificantMove(Math.abs(delta), pageOrientedSize);
|
||||
|
||||
mTotalMotion += Math.abs(mLastMotion + mLastMotionRemainder - primaryDirection);
|
||||
mTotalMotion += Math.abs(mLastMotion - primaryDirection);
|
||||
boolean passedSlop = mAllowEasyFling || mTotalMotion > mPageSlop;
|
||||
boolean isFling = passedSlop && shouldFlingForVelocity(velocity);
|
||||
boolean isDeltaLeft = mIsRtl ? delta > 0 : delta < 0;
|
||||
@@ -1562,9 +1559,8 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
||||
// active pointer and adjust accordingly.
|
||||
// TODO: Make this decision more intelligent.
|
||||
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
|
||||
mLastMotion = mDownMotionPrimary = mOrientationHandler.getPrimaryDirection(ev,
|
||||
newPointerIndex);
|
||||
mLastMotionRemainder = 0;
|
||||
mDownMotionPrimary = mOrientationHandler.getPrimaryDirection(ev, newPointerIndex);
|
||||
mLastMotion = (int) mDownMotionPrimary;
|
||||
mActivePointerId = ev.getPointerId(newPointerIndex);
|
||||
if (mVelocityTracker != null) {
|
||||
mVelocityTracker.clear();
|
||||
|
||||
@@ -41,11 +41,9 @@ public class FlingSpringAnim {
|
||||
|
||||
public <K> FlingSpringAnim(K object, Context context, FloatPropertyCompat<K> property,
|
||||
float startPosition, float targetPosition, float startVelocityPxPerS,
|
||||
float minVisChange, float minValue, float maxValue,
|
||||
float minVisChange, float minValue, float maxValue, float damping, float stiffness,
|
||||
OnAnimationEndListener onEndListener) {
|
||||
ResourceProvider rp = DynamicResource.provider(context);
|
||||
float damping = rp.getFloat(R.dimen.swipe_up_rect_xy_damping_ratio);
|
||||
float stiffness = rp.getFloat(R.dimen.swipe_up_rect_xy_stiffness);
|
||||
float friction = rp.getFloat(R.dimen.swipe_up_rect_xy_fling_friction);
|
||||
|
||||
mFlingAnim = new FlingAnimation(object, property)
|
||||
|
||||
@@ -286,7 +286,7 @@ public final class FeatureFlags {
|
||||
"Use local overrides for search request timeout");
|
||||
|
||||
public static final BooleanFlag CONTINUOUS_VIEW_TREE_CAPTURE = getDebugFlag(270395171,
|
||||
"CONTINUOUS_VIEW_TREE_CAPTURE", false, "Capture View tree every frame");
|
||||
"CONTINUOUS_VIEW_TREE_CAPTURE", true, "Capture View tree every frame");
|
||||
|
||||
public static final BooleanFlag SECONDARY_DRAG_N_DROP_TO_PIN = getDebugFlag(
|
||||
270395140, "SECONDARY_DRAG_N_DROP_TO_PIN", false,
|
||||
|
||||
@@ -306,6 +306,13 @@ public class ItemInfo {
|
||||
return container == CONTAINER_HOTSEAT_PREDICTION || container == CONTAINER_PREDICTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if an Item is in the hotseat.
|
||||
*/
|
||||
public boolean isInHotseat() {
|
||||
return container == CONTAINER_HOTSEAT || container == CONTAINER_HOTSEAT_PREDICTION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this item should use the background animation.
|
||||
*/
|
||||
|
||||
@@ -43,9 +43,6 @@ import android.view.ViewGroup.MarginLayoutParams;
|
||||
import android.view.ViewOutlineProvider;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.dynamicanimation.animation.FloatPropertyCompat;
|
||||
import androidx.dynamicanimation.animation.SpringAnimation;
|
||||
import androidx.dynamicanimation.animation.SpringForce;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
@@ -63,39 +60,6 @@ public class ClipIconView extends View implements ClipPathView {
|
||||
|
||||
private static final Rect sTmpRect = new Rect();
|
||||
|
||||
// We spring the foreground drawable relative to the icon's movement in the DragLayer.
|
||||
// We then use these two factor values to scale the movement of the fg within this view.
|
||||
private static final int FG_TRANS_X_FACTOR = 60;
|
||||
private static final int FG_TRANS_Y_FACTOR = 75;
|
||||
|
||||
private static final FloatPropertyCompat<ClipIconView> mFgTransYProperty =
|
||||
new FloatPropertyCompat<ClipIconView>("ClipIconViewFgTransY") {
|
||||
@Override
|
||||
public float getValue(ClipIconView view) {
|
||||
return view.mFgTransY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(ClipIconView view, float transY) {
|
||||
view.mFgTransY = transY;
|
||||
view.invalidate();
|
||||
}
|
||||
};
|
||||
|
||||
private static final FloatPropertyCompat<ClipIconView> mFgTransXProperty =
|
||||
new FloatPropertyCompat<ClipIconView>("ClipIconViewFgTransX") {
|
||||
@Override
|
||||
public float getValue(ClipIconView view) {
|
||||
return view.mFgTransX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(ClipIconView view, float transX) {
|
||||
view.mFgTransX = transX;
|
||||
view.invalidate();
|
||||
}
|
||||
};
|
||||
|
||||
private final int mBlurSizeOutline;
|
||||
private final boolean mIsRtl;
|
||||
|
||||
@@ -114,11 +78,6 @@ public class ClipIconView extends View implements ClipPathView {
|
||||
private final Rect mOutline = new Rect();
|
||||
private final Rect mFinalDrawableBounds = new Rect();
|
||||
|
||||
private final SpringAnimation mFgSpringY;
|
||||
private float mFgTransY;
|
||||
private final SpringAnimation mFgSpringX;
|
||||
private float mFgTransX;
|
||||
|
||||
public ClipIconView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -132,22 +91,13 @@ public class ClipIconView extends View implements ClipPathView {
|
||||
mBlurSizeOutline = getResources().getDimensionPixelSize(
|
||||
R.dimen.blur_size_medium_outline);
|
||||
mIsRtl = Utilities.isRtl(getResources());
|
||||
|
||||
mFgSpringX = new SpringAnimation(this, mFgTransXProperty)
|
||||
.setSpring(new SpringForce()
|
||||
.setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
|
||||
.setStiffness(SpringForce.STIFFNESS_LOW));
|
||||
mFgSpringY = new SpringAnimation(this, mFgTransYProperty)
|
||||
.setSpring(new SpringForce()
|
||||
.setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
|
||||
.setStiffness(SpringForce.STIFFNESS_LOW));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the icon UI to match the provided parameters during an animation frame
|
||||
*/
|
||||
public void update(RectF rect, float progress, float shapeProgressStart, float cornerRadius,
|
||||
int fgIconAlpha, boolean isOpening, View container, DeviceProfile dp) {
|
||||
boolean isOpening, View container, DeviceProfile dp) {
|
||||
MarginLayoutParams lp = (MarginLayoutParams) container.getLayoutParams();
|
||||
|
||||
float dX = mIsRtl
|
||||
@@ -167,8 +117,7 @@ public class ClipIconView extends View implements ClipPathView {
|
||||
return;
|
||||
}
|
||||
|
||||
update(rect, progress, shapeProgressStart, cornerRadius, fgIconAlpha, isOpening, scale,
|
||||
minSize, lp, dp);
|
||||
update(rect, progress, shapeProgressStart, cornerRadius, isOpening, scale, minSize, dp);
|
||||
|
||||
container.setPivotX(0);
|
||||
container.setPivotY(0);
|
||||
@@ -179,13 +128,7 @@ public class ClipIconView extends View implements ClipPathView {
|
||||
}
|
||||
|
||||
private void update(RectF rect, float progress, float shapeProgressStart, float cornerRadius,
|
||||
int fgIconAlpha, boolean isOpening, float scale, float minSize,
|
||||
MarginLayoutParams parentLp, DeviceProfile dp) {
|
||||
float dX = mIsRtl
|
||||
? rect.left - (dp.widthPx - parentLp.getMarginStart() - parentLp.width)
|
||||
: rect.left - parentLp.getMarginStart();
|
||||
float dY = rect.top - parentLp.topMargin;
|
||||
|
||||
boolean isOpening, float scale, float minSize, DeviceProfile dp) {
|
||||
// shapeRevealProgress = 1 when progress = shapeProgressStart + SHAPE_PROGRESS_DURATION
|
||||
float toMax = isOpening ? 1 / SHAPE_PROGRESS_DURATION : 1f;
|
||||
|
||||
@@ -220,27 +163,17 @@ public class ClipIconView extends View implements ClipPathView {
|
||||
float drawableScale = (dp.isLandscape ? mOutline.width() : mOutline.height())
|
||||
/ minSize;
|
||||
setBackgroundDrawableBounds(drawableScale, dp.isLandscape);
|
||||
if (isOpening) {
|
||||
// Center align foreground
|
||||
int height = mFinalDrawableBounds.height();
|
||||
int width = mFinalDrawableBounds.width();
|
||||
int diffY = dp.isLandscape ? 0
|
||||
: (int) (((height * drawableScale) - height) / 2);
|
||||
int diffX = dp.isLandscape ? (int) (((width * drawableScale) - width) / 2)
|
||||
: 0;
|
||||
sTmpRect.set(mFinalDrawableBounds);
|
||||
sTmpRect.offset(diffX, diffY);
|
||||
mForeground.setBounds(sTmpRect);
|
||||
} else {
|
||||
mForeground.setAlpha(fgIconAlpha);
|
||||
|
||||
// Spring the foreground relative to the icon's movement within the DragLayer.
|
||||
int diffX = (int) (dX / dp.availableWidthPx * FG_TRANS_X_FACTOR);
|
||||
int diffY = (int) (dY / dp.availableHeightPx * FG_TRANS_Y_FACTOR);
|
||||
|
||||
mFgSpringX.animateToFinalPosition(diffX);
|
||||
mFgSpringY.animateToFinalPosition(diffY);
|
||||
}
|
||||
// Center align foreground
|
||||
int height = mFinalDrawableBounds.height();
|
||||
int width = mFinalDrawableBounds.width();
|
||||
int diffY = dp.isLandscape ? 0
|
||||
: (int) (((height * drawableScale) - height) / 2);
|
||||
int diffX = dp.isLandscape ? (int) (((width * drawableScale) - width) / 2)
|
||||
: 0;
|
||||
sTmpRect.set(mFinalDrawableBounds);
|
||||
sTmpRect.offset(diffX, diffY);
|
||||
mForeground.setBounds(sTmpRect);
|
||||
}
|
||||
invalidate();
|
||||
invalidateOutline();
|
||||
@@ -359,10 +292,7 @@ public class ClipIconView extends View implements ClipPathView {
|
||||
mBackground.draw(canvas);
|
||||
}
|
||||
if (mForeground != null) {
|
||||
int count2 = canvas.save();
|
||||
canvas.translate(mFgTransX, mFgTransY);
|
||||
mForeground.draw(canvas);
|
||||
canvas.restoreToCount(count2);
|
||||
}
|
||||
canvas.restoreToCount(count);
|
||||
}
|
||||
@@ -380,9 +310,5 @@ public class ClipIconView extends View implements ClipPathView {
|
||||
mRevealAnimator = null;
|
||||
mTaskCornerRadius = 0;
|
||||
mOutline.setEmpty();
|
||||
mFgTransY = 0;
|
||||
mFgSpringX.cancel();
|
||||
mFgTransX = 0;
|
||||
mFgSpringY.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,17 +146,16 @@ public class FloatingIconView extends FrameLayout implements
|
||||
/**
|
||||
* Positions this view to match the size and location of {@param rect}.
|
||||
* @param alpha The alpha[0, 1] of the entire floating view.
|
||||
* @param fgIconAlpha The alpha[0-255] of the foreground layer of the icon (if applicable).
|
||||
* @param progress A value from [0, 1] that represents the animation progress.
|
||||
* @param shapeProgressStart The progress value at which to start the shape reveal.
|
||||
* @param cornerRadius The corner radius of {@param rect}.
|
||||
* @param isOpening True if view is used for app open animation, false for app close animation.
|
||||
*/
|
||||
public void update(float alpha, int fgIconAlpha, RectF rect, float progress,
|
||||
float shapeProgressStart, float cornerRadius, boolean isOpening) {
|
||||
public void update(float alpha, RectF rect, float progress, float shapeProgressStart,
|
||||
float cornerRadius, boolean isOpening) {
|
||||
setAlpha(alpha);
|
||||
mClipIconView.update(rect, progress, shapeProgressStart, cornerRadius, fgIconAlpha,
|
||||
isOpening, this, mLauncher.getDeviceProfile());
|
||||
mClipIconView.update(rect, progress, shapeProgressStart, cornerRadius, isOpening, this,
|
||||
mLauncher.getDeviceProfile());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -342,15 +342,15 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
|
||||
"\ticonDrawablePaddingPx: 0.0px (0.0dp)\n" +
|
||||
"\tinv.numFolderRows: 4\n" +
|
||||
"\tinv.numFolderColumns: 4\n" +
|
||||
"\tfolderCellWidthPx: 142.0px (54.095238dp)\n" +
|
||||
"\tfolderCellHeightPx: 168.0px (64.0dp)\n" +
|
||||
"\tfolderChildIconSizePx: 108.0px (41.142857dp)\n" +
|
||||
"\tfolderChildTextSizePx: 28.0px (10.666667dp)\n" +
|
||||
"\tfolderChildDrawablePaddingPx: 7.0px (2.6666667dp)\n" +
|
||||
"\tfolderCellWidthPx: 173.0px (65.90476dp)\n" +
|
||||
"\tfolderCellHeightPx: 205.0px (78.09524dp)\n" +
|
||||
"\tfolderChildIconSizePx: 131.0px (49.904762dp)\n" +
|
||||
"\tfolderChildTextSizePx: 34.0px (12.952381dp)\n" +
|
||||
"\tfolderChildDrawablePaddingPx: 9.0px (3.4285715dp)\n" +
|
||||
"\tfolderCellLayoutBorderSpacePx: 0.0px (0.0dp)\n" +
|
||||
"\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
|
||||
"\tfolderTopPadding: 63.0px (24.0dp)\n" +
|
||||
"\tfolderFooterHeight: 147.0px (56.0dp)\n" +
|
||||
"\tfolderTopPadding: 56.0px (21.333334dp)\n" +
|
||||
"\tfolderFooterHeight: 131.0px (49.904762dp)\n" +
|
||||
"\tbottomSheetTopPadding: 114.0px (43.42857dp)\n" +
|
||||
"\tbottomSheetOpenDuration: 267\n" +
|
||||
"\tbottomSheetCloseDuration: 267\n" +
|
||||
@@ -474,15 +474,15 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
|
||||
"\ticonDrawablePaddingPx: 0.0px (0.0dp)\n" +
|
||||
"\tinv.numFolderRows: 4\n" +
|
||||
"\tinv.numFolderColumns: 4\n" +
|
||||
"\tfolderCellWidthPx: 128.0px (48.761906dp)\n" +
|
||||
"\tfolderCellHeightPx: 152.0px (57.904762dp)\n" +
|
||||
"\tfolderChildIconSizePx: 98.0px (37.333332dp)\n" +
|
||||
"\tfolderChildTextSizePx: 25.0px (9.523809dp)\n" +
|
||||
"\tfolderChildDrawablePaddingPx: 6.0px (2.2857144dp)\n" +
|
||||
"\tfolderCellWidthPx: 163.0px (62.095238dp)\n" +
|
||||
"\tfolderCellHeightPx: 192.0px (73.14286dp)\n" +
|
||||
"\tfolderChildIconSizePx: 123.0px (46.857143dp)\n" +
|
||||
"\tfolderChildTextSizePx: 32.0px (12.190476dp)\n" +
|
||||
"\tfolderChildDrawablePaddingPx: 8.0px (3.047619dp)\n" +
|
||||
"\tfolderCellLayoutBorderSpacePx: 0.0px (0.0dp)\n" +
|
||||
"\tfolderContentPaddingLeftRight: 21.0px (8.0dp)\n" +
|
||||
"\tfolderTopPadding: 63.0px (24.0dp)\n" +
|
||||
"\tfolderFooterHeight: 147.0px (56.0dp)\n" +
|
||||
"\tfolderTopPadding: 53.0px (20.190475dp)\n" +
|
||||
"\tfolderFooterHeight: 123.0px (46.857143dp)\n" +
|
||||
"\tbottomSheetTopPadding: 114.0px (43.42857dp)\n" +
|
||||
"\tbottomSheetOpenDuration: 267\n" +
|
||||
"\tbottomSheetCloseDuration: 267\n" +
|
||||
@@ -607,15 +607,15 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
|
||||
"\ticonDrawablePaddingPx: 14.0px (7.0dp)\n" +
|
||||
"\tinv.numFolderRows: 3\n" +
|
||||
"\tinv.numFolderColumns: 3\n" +
|
||||
"\tfolderCellWidthPx: 397.0px (198.5dp)\n" +
|
||||
"\tfolderCellHeightPx: 371.0px (185.5dp)\n" +
|
||||
"\tfolderChildIconSizePx: 99.0px (49.5dp)\n" +
|
||||
"\tfolderChildTextSizePx: 23.0px (11.5dp)\n" +
|
||||
"\tfolderChildDrawablePaddingPx: 80.0px (40.0dp)\n" +
|
||||
"\tfolderCellWidthPx: 240.0px (120.0dp)\n" +
|
||||
"\tfolderCellHeightPx: 208.0px (104.0dp)\n" +
|
||||
"\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
|
||||
"\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
|
||||
"\tfolderChildDrawablePaddingPx: 16.0px (8.0dp)\n" +
|
||||
"\tfolderCellLayoutBorderSpacePx: 0.0px (0.0dp)\n" +
|
||||
"\tfolderContentPaddingLeftRight: 0.0px (0.0dp)\n" +
|
||||
"\tfolderTopPadding: 48.0px (24.0dp)\n" +
|
||||
"\tfolderFooterHeight: 0.0px (0.0dp)\n" +
|
||||
"\tfolderFooterHeight: 112.0px (56.0dp)\n" +
|
||||
"\tbottomSheetTopPadding: 104.0px (52.0dp)\n" +
|
||||
"\tbottomSheetOpenDuration: 500\n" +
|
||||
"\tbottomSheetCloseDuration: 500\n" +
|
||||
@@ -740,15 +740,15 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
|
||||
"\ticonDrawablePaddingPx: 14.0px (7.0dp)\n" +
|
||||
"\tinv.numFolderRows: 3\n" +
|
||||
"\tinv.numFolderColumns: 3\n" +
|
||||
"\tfolderCellWidthPx: 397.0px (198.5dp)\n" +
|
||||
"\tfolderCellHeightPx: 371.0px (185.5dp)\n" +
|
||||
"\tfolderChildIconSizePx: 99.0px (49.5dp)\n" +
|
||||
"\tfolderChildTextSizePx: 23.0px (11.5dp)\n" +
|
||||
"\tfolderChildDrawablePaddingPx: 80.0px (40.0dp)\n" +
|
||||
"\tfolderCellWidthPx: 240.0px (120.0dp)\n" +
|
||||
"\tfolderCellHeightPx: 208.0px (104.0dp)\n" +
|
||||
"\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
|
||||
"\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
|
||||
"\tfolderChildDrawablePaddingPx: 16.0px (8.0dp)\n" +
|
||||
"\tfolderCellLayoutBorderSpacePx: 0.0px (0.0dp)\n" +
|
||||
"\tfolderContentPaddingLeftRight: 0.0px (0.0dp)\n" +
|
||||
"\tfolderTopPadding: 48.0px (24.0dp)\n" +
|
||||
"\tfolderFooterHeight: 0.0px (0.0dp)\n" +
|
||||
"\tfolderFooterHeight: 112.0px (56.0dp)\n" +
|
||||
"\tbottomSheetTopPadding: 104.0px (52.0dp)\n" +
|
||||
"\tbottomSheetOpenDuration: 500\n" +
|
||||
"\tbottomSheetCloseDuration: 500\n" +
|
||||
@@ -873,15 +873,15 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
|
||||
"\ticonDrawablePaddingPx: 14.0px (7.0dp)\n" +
|
||||
"\tinv.numFolderRows: 3\n" +
|
||||
"\tinv.numFolderColumns: 3\n" +
|
||||
"\tfolderCellWidthPx: 408.0px (204.0dp)\n" +
|
||||
"\tfolderCellHeightPx: 648.0px (324.0dp)\n" +
|
||||
"\tfolderCellWidthPx: 204.0px (102.0dp)\n" +
|
||||
"\tfolderCellHeightPx: 240.0px (120.0dp)\n" +
|
||||
"\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
|
||||
"\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
|
||||
"\tfolderChildDrawablePaddingPx: 163.0px (81.5dp)\n" +
|
||||
"\tfolderChildDrawablePaddingPx: 27.0px (13.5dp)\n" +
|
||||
"\tfolderCellLayoutBorderSpacePx: 0.0px (0.0dp)\n" +
|
||||
"\tfolderContentPaddingLeftRight: 0.0px (0.0dp)\n" +
|
||||
"\tfolderTopPadding: 48.0px (24.0dp)\n" +
|
||||
"\tfolderFooterHeight: 0.0px (0.0dp)\n" +
|
||||
"\tfolderFooterHeight: 112.0px (56.0dp)\n" +
|
||||
"\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
|
||||
"\tbottomSheetOpenDuration: 500\n" +
|
||||
"\tbottomSheetCloseDuration: 500\n" +
|
||||
@@ -1006,15 +1006,15 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() {
|
||||
"\ticonDrawablePaddingPx: 14.0px (7.0dp)\n" +
|
||||
"\tinv.numFolderRows: 3\n" +
|
||||
"\tinv.numFolderColumns: 3\n" +
|
||||
"\tfolderCellWidthPx: 408.0px (204.0dp)\n" +
|
||||
"\tfolderCellHeightPx: 648.0px (324.0dp)\n" +
|
||||
"\tfolderCellWidthPx: 204.0px (102.0dp)\n" +
|
||||
"\tfolderCellHeightPx: 240.0px (120.0dp)\n" +
|
||||
"\tfolderChildIconSizePx: 120.0px (60.0dp)\n" +
|
||||
"\tfolderChildTextSizePx: 28.0px (14.0dp)\n" +
|
||||
"\tfolderChildDrawablePaddingPx: 163.0px (81.5dp)\n" +
|
||||
"\tfolderChildDrawablePaddingPx: 27.0px (13.5dp)\n" +
|
||||
"\tfolderCellLayoutBorderSpacePx: 0.0px (0.0dp)\n" +
|
||||
"\tfolderContentPaddingLeftRight: 0.0px (0.0dp)\n" +
|
||||
"\tfolderTopPadding: 48.0px (24.0dp)\n" +
|
||||
"\tfolderFooterHeight: 0.0px (0.0dp)\n" +
|
||||
"\tfolderFooterHeight: 112.0px (56.0dp)\n" +
|
||||
"\tbottomSheetTopPadding: 704.0px (352.0dp)\n" +
|
||||
"\tbottomSheetOpenDuration: 500\n" +
|
||||
"\tbottomSheetCloseDuration: 500\n" +
|
||||
|
||||
Reference in New Issue
Block a user