978b0021a9
This patch fixes two bugs related to the way tiles slide in when a split is staged. Previously, translations were not being completely reset, so on repeated splits, the thumbnails would retain their old translation setting and cause awkward movements to occur during the slide-in animation. Fixed by adding setTaskViewsPrimarySplitTranslation() and setTaskViewsSecondarySplitTranslation() in resetFromSplitSelectionState(). Fixes: 249154347 Fixes: 249824716 Test: Manual on grid and non-grid Overview, in a variety of conditions Change-Id: I2d9aa621a17f178ff8216740d76429d2ac484b39
172 lines
7.6 KiB
Java
172 lines
7.6 KiB
Java
/*
|
|
* Copyright (C) 2017 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.launcher3.uioverrides;
|
|
|
|
import static com.android.launcher3.LauncherState.CLEAR_ALL_BUTTON;
|
|
import static com.android.launcher3.LauncherState.OVERVIEW_ACTIONS;
|
|
import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT;
|
|
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
|
import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE;
|
|
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
|
|
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
|
|
import static com.android.quickstep.views.RecentsView.TASK_MODALNESS;
|
|
import static com.android.quickstep.views.RecentsView.TASK_PRIMARY_SPLIT_TRANSLATION;
|
|
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_SPLIT_TRANSLATION;
|
|
import static com.android.quickstep.views.TaskView.FLAG_UPDATE_ALL;
|
|
|
|
import android.animation.AnimatorSet;
|
|
import android.annotation.TargetApi;
|
|
import android.os.Build;
|
|
import android.util.FloatProperty;
|
|
import android.util.Pair;
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
import com.android.launcher3.LauncherState;
|
|
import com.android.launcher3.anim.AnimatorListeners;
|
|
import com.android.launcher3.anim.PendingAnimation;
|
|
import com.android.launcher3.anim.PropertySetter;
|
|
import com.android.launcher3.states.StateAnimationConfig;
|
|
import com.android.launcher3.touch.PagedOrientationHandler;
|
|
import com.android.launcher3.util.MultiValueAlpha;
|
|
import com.android.quickstep.util.AnimUtils;
|
|
import com.android.quickstep.util.SplitAnimationTimings;
|
|
import com.android.quickstep.views.ClearAllButton;
|
|
import com.android.quickstep.views.LauncherRecentsView;
|
|
import com.android.quickstep.views.RecentsView;
|
|
|
|
/**
|
|
* State handler for handling UI changes for {@link LauncherRecentsView}. In addition to managing
|
|
* the basic view properties, this class also manages changes in the task visuals.
|
|
*/
|
|
@TargetApi(Build.VERSION_CODES.O)
|
|
public final class RecentsViewStateController extends
|
|
BaseRecentsViewStateController<LauncherRecentsView> {
|
|
|
|
public RecentsViewStateController(QuickstepLauncher launcher) {
|
|
super(launcher);
|
|
}
|
|
|
|
@Override
|
|
public void setState(@NonNull LauncherState state) {
|
|
super.setState(state);
|
|
if (state.overviewUi) {
|
|
mRecentsView.updateEmptyMessage();
|
|
mRecentsView.resetTaskVisuals();
|
|
}
|
|
setAlphas(PropertySetter.NO_ANIM_PROPERTY_SETTER, new StateAnimationConfig(), state);
|
|
mRecentsView.setFullscreenProgress(state.getOverviewFullscreenProgress());
|
|
// In Overview, we may be layering app surfaces behind Launcher, so we need to notify
|
|
// DepthController to prevent optimizations which might occlude the layers behind
|
|
mLauncher.getDepthController().setHasContentBehindLauncher(state.overviewUi);
|
|
|
|
PendingAnimation builder =
|
|
new PendingAnimation(state.getTransitionDuration(mLauncher, true));
|
|
|
|
handleSplitSelectionState(state, builder, /* animate */false);
|
|
}
|
|
|
|
@Override
|
|
void setStateWithAnimationInternal(@NonNull LauncherState toState,
|
|
@NonNull StateAnimationConfig config, @NonNull PendingAnimation builder) {
|
|
super.setStateWithAnimationInternal(toState, config, builder);
|
|
|
|
if (toState.overviewUi) {
|
|
// While animating into recents, update the visible task data as needed
|
|
builder.addOnFrameCallback(() -> mRecentsView.loadVisibleTaskData(FLAG_UPDATE_ALL));
|
|
mRecentsView.updateEmptyMessage();
|
|
} else {
|
|
builder.addListener(
|
|
AnimatorListeners.forSuccessCallback(mRecentsView::resetTaskVisuals));
|
|
}
|
|
// In Overview, we may be layering app surfaces behind Launcher, so we need to notify
|
|
// DepthController to prevent optimizations which might occlude the layers behind
|
|
builder.addListener(AnimatorListeners.forSuccessCallback(() ->
|
|
mLauncher.getDepthController().setHasContentBehindLauncher(toState.overviewUi)));
|
|
|
|
handleSplitSelectionState(toState, builder, /* animate */true);
|
|
|
|
setAlphas(builder, config, toState);
|
|
builder.setFloat(mRecentsView, FULLSCREEN_PROGRESS,
|
|
toState.getOverviewFullscreenProgress(), LINEAR);
|
|
}
|
|
|
|
/**
|
|
* Create or dismiss split screen select animations.
|
|
* @param builder if null then this will run the split select animations right away, otherwise
|
|
* will add animations to builder.
|
|
*/
|
|
private void handleSplitSelectionState(@NonNull LauncherState toState,
|
|
@NonNull PendingAnimation builder, boolean animate) {
|
|
if (toState != OVERVIEW_SPLIT_SELECT) {
|
|
// Not going to split, nothing to do but ensure taskviews are at correct offset
|
|
mRecentsView.resetSplitPrimaryScrollOffset();
|
|
return;
|
|
}
|
|
|
|
// Create transition animations to split select
|
|
PagedOrientationHandler orientationHandler =
|
|
((RecentsView) mLauncher.getOverviewPanel()).getPagedOrientationHandler();
|
|
Pair<FloatProperty, FloatProperty> taskViewsFloat =
|
|
orientationHandler.getSplitSelectTaskOffset(
|
|
TASK_PRIMARY_SPLIT_TRANSLATION, TASK_SECONDARY_SPLIT_TRANSLATION,
|
|
mLauncher.getDeviceProfile());
|
|
|
|
SplitAnimationTimings timings =
|
|
AnimUtils.getDeviceOverviewToSplitTimings(mLauncher.getDeviceProfile().isTablet);
|
|
|
|
mRecentsView.createSplitSelectInitAnimation(builder,
|
|
toState.getTransitionDuration(mLauncher, true /* isToState */));
|
|
// Shift tasks vertically downward to get out of placeholder view
|
|
builder.setFloat(mRecentsView, taskViewsFloat.first,
|
|
toState.getSplitSelectTranslation(mLauncher),
|
|
timings.getGridSlidePrimaryInterpolator());
|
|
// Zero out horizontal translation
|
|
builder.setFloat(mRecentsView, taskViewsFloat.second,
|
|
0,
|
|
timings.getGridSlideSecondaryInterpolator());
|
|
|
|
if (!animate) {
|
|
AnimatorSet as = builder.buildAnim();
|
|
as.start();
|
|
as.end();
|
|
}
|
|
|
|
mRecentsView.applySplitPrimaryScrollOffset();
|
|
}
|
|
|
|
private void setAlphas(PropertySetter propertySetter, StateAnimationConfig config,
|
|
LauncherState state) {
|
|
float clearAllButtonAlpha = state.areElementsVisible(mLauncher, CLEAR_ALL_BUTTON) ? 1 : 0;
|
|
propertySetter.setFloat(mRecentsView.getClearAllButton(), ClearAllButton.VISIBILITY_ALPHA,
|
|
clearAllButtonAlpha, LINEAR);
|
|
float overviewButtonAlpha = state.areElementsVisible(mLauncher, OVERVIEW_ACTIONS) ? 1 : 0;
|
|
propertySetter.setFloat(mLauncher.getActionsView().getVisibilityAlpha(),
|
|
MultiValueAlpha.VALUE, overviewButtonAlpha, config.getInterpolator(
|
|
ANIM_OVERVIEW_ACTIONS_FADE, LINEAR));
|
|
}
|
|
|
|
@Override
|
|
FloatProperty<RecentsView> getTaskModalnessProperty() {
|
|
return TASK_MODALNESS;
|
|
}
|
|
|
|
@Override
|
|
FloatProperty<RecentsView> getContentAlphaProperty() {
|
|
return CONTENT_ALPHA;
|
|
}
|
|
}
|