cd44740567
Bug: 301661768 Test: Presubmit Flag: N/A Change-Id: Iec8a5e739f394a152d5ffc57b01e0449e94b4084
164 lines
5.3 KiB
Java
164 lines
5.3 KiB
Java
/*
|
|
* Copyright (C) 2018 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.allapps;
|
|
|
|
import static com.android.launcher3.LauncherState.NORMAL;
|
|
import static com.android.launcher3.util.OnboardingPrefs.HOME_BOUNCE_SEEN;
|
|
|
|
import android.animation.Animator;
|
|
import android.animation.AnimatorInflater;
|
|
import android.os.Handler;
|
|
import android.os.UserManager;
|
|
import android.view.MotionEvent;
|
|
import android.view.View;
|
|
|
|
import com.android.launcher3.AbstractFloatingView;
|
|
import com.android.launcher3.Launcher;
|
|
import com.android.launcher3.LauncherState;
|
|
import com.android.launcher3.R;
|
|
import com.android.launcher3.Utilities;
|
|
import com.android.launcher3.anim.AnimatorListeners;
|
|
import com.android.launcher3.statemanager.StateManager.StateListener;
|
|
import com.android.launcher3.util.OnboardingPrefs;
|
|
|
|
/**
|
|
* Abstract base class of floating view responsible for showing discovery bounce animation
|
|
*/
|
|
public class DiscoveryBounce extends AbstractFloatingView {
|
|
|
|
private static final long DELAY_MS = 450;
|
|
|
|
private final Launcher mLauncher;
|
|
private final Animator mDiscoBounceAnimation;
|
|
|
|
private final StateListener<LauncherState> mStateListener = new StateListener<LauncherState>() {
|
|
@Override
|
|
public void onStateTransitionStart(LauncherState toState) {
|
|
handleClose(false);
|
|
}
|
|
|
|
@Override
|
|
public void onStateTransitionComplete(LauncherState finalState) {}
|
|
};
|
|
|
|
public DiscoveryBounce(Launcher launcher) {
|
|
super(launcher, null);
|
|
mLauncher = launcher;
|
|
|
|
mDiscoBounceAnimation =
|
|
AnimatorInflater.loadAnimator(launcher, R.animator.discovery_bounce);
|
|
mDiscoBounceAnimation.setTarget(new VerticalProgressWrapper(
|
|
launcher.getHotseat(), mLauncher.getDragLayer().getHeight()));
|
|
mDiscoBounceAnimation.addListener(AnimatorListeners.forEndCallback(this::handleClose));
|
|
launcher.getStateManager().addStateListener(mStateListener);
|
|
}
|
|
|
|
@Override
|
|
protected void onAttachedToWindow() {
|
|
super.onAttachedToWindow();
|
|
mDiscoBounceAnimation.start();
|
|
}
|
|
|
|
@Override
|
|
protected void onDetachedFromWindow() {
|
|
super.onDetachedFromWindow();
|
|
if (mDiscoBounceAnimation.isRunning()) {
|
|
mDiscoBounceAnimation.end();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean canHandleBack() {
|
|
// Since DiscoveryBounce doesn't handle back, onBackInvoked() won't be called and we should
|
|
// close it without animation.
|
|
close(false);
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
|
|
handleClose(false);
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
protected void handleClose(boolean animate) {
|
|
if (mIsOpen) {
|
|
mIsOpen = false;
|
|
mLauncher.getDragLayer().removeView(this);
|
|
// Reset the translation to what ever it was previously.
|
|
mLauncher.getHotseat().setTranslationY(mLauncher.getStateManager().getState()
|
|
.getHotseatScaleAndTranslation(mLauncher).translationY);
|
|
mLauncher.getStateManager().removeStateListener(mStateListener);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected boolean isOfType(int type) {
|
|
return (type & TYPE_DISCOVERY_BOUNCE) != 0;
|
|
}
|
|
|
|
private void show() {
|
|
mIsOpen = true;
|
|
mLauncher.getDragLayer().addView(this);
|
|
// TODO: add WW log for discovery bounce tip show event.
|
|
}
|
|
|
|
public static void showForHomeIfNeeded(Launcher launcher) {
|
|
showForHomeIfNeeded(launcher, true);
|
|
}
|
|
|
|
private static void showForHomeIfNeeded(Launcher launcher, boolean withDelay) {
|
|
if (!launcher.isInState(NORMAL)
|
|
|| HOME_BOUNCE_SEEN.get(launcher)
|
|
|| AbstractFloatingView.getTopOpenView(launcher) != null
|
|
|| launcher.getSystemService(UserManager.class).isDemoUser()
|
|
|| Utilities.isRunningInTestHarness()) {
|
|
return;
|
|
}
|
|
|
|
if (withDelay) {
|
|
new Handler().postDelayed(() -> showForHomeIfNeeded(launcher, false), DELAY_MS);
|
|
return;
|
|
}
|
|
OnboardingPrefs.HOME_BOUNCE_COUNT.increment(launcher);
|
|
new DiscoveryBounce(launcher).show();
|
|
}
|
|
|
|
/**
|
|
* A wrapper around hotseat animator allowing a fixed shift in the value.
|
|
*/
|
|
public static class VerticalProgressWrapper {
|
|
|
|
private final View mView;
|
|
private final float mLimit;
|
|
|
|
private VerticalProgressWrapper(View view, float limit) {
|
|
mView = view;
|
|
mLimit = limit;
|
|
}
|
|
|
|
public float getProgress() {
|
|
return 1 + mView.getTranslationY() / mLimit;
|
|
}
|
|
|
|
public void setProgress(float progress) {
|
|
mView.setTranslationY(mLimit * (progress - 1));
|
|
}
|
|
}
|
|
}
|