Pull up all apps interaction
First phase implementation: dragging and animation interaction is implemented namely in two classes. ScrollGestureDetector and AllAppsTransitionController. FeatureFlag.LAUNCHER#_ALL_APPS_PULL_UP will be true for only AOSP and not in the extending builds. This way, we can safely iterate without turning it on the shipped ready version. b/28917826 Change-Id: I0501309c0121880ffe0555f82d6ac5a145581bb1
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
package com.android.launcher3.allapps;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
/**
|
||||
* One dimensional scroll gesture detector for all apps container pull up interaction.
|
||||
*/
|
||||
public class VerticalPullDetector {
|
||||
|
||||
private static final String TAG = "ScrollGesture";
|
||||
private static final boolean DBG = false;
|
||||
|
||||
private float mTouchSlop;
|
||||
|
||||
private boolean mAllAppsVisible;
|
||||
private boolean mAllAppsScrollAtTop;
|
||||
|
||||
/**
|
||||
* The minimum release velocity in pixels per millisecond that triggers fling..
|
||||
*/
|
||||
private static final float RELEASE_VELOCITY_PX_MS = 1.7f;
|
||||
|
||||
/**
|
||||
* The time constant used to calculate dampening in the low-pass filter of scroll velocity.
|
||||
* Cutoff frequency is set at 10 Hz.
|
||||
*/
|
||||
public static final float SCROLL_VELOCITY_DAMPENING_RC = 1000f / (2f * (float) Math.PI * 10);
|
||||
|
||||
/* Scroll state, this is set to true during dragging and animation. */
|
||||
boolean mScrolling;
|
||||
|
||||
|
||||
float mDownY;
|
||||
float mDownMillis;
|
||||
|
||||
float mLastY;
|
||||
float mLastMillis;
|
||||
|
||||
float mVelocity;
|
||||
float mLastDisplacement;
|
||||
float mDisplacement;
|
||||
|
||||
/* scroll started during previous animation */
|
||||
boolean mSubtractSlop = true;
|
||||
|
||||
/* Client of this gesture detector can register a callback. */
|
||||
Listener mListener;
|
||||
|
||||
public void setListener(Listener l) {
|
||||
mListener = l;
|
||||
}
|
||||
|
||||
interface Listener{
|
||||
/**
|
||||
* @param start when should
|
||||
*/
|
||||
void onScrollStart(boolean start);
|
||||
boolean onScroll(float displacement, float velocity);
|
||||
void onScrollEnd(float velocity, boolean fling);
|
||||
}
|
||||
|
||||
public VerticalPullDetector(Context context) {
|
||||
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
|
||||
}
|
||||
|
||||
public void setAllAppsState(boolean allAppsVisible, boolean scrollAtTop) {
|
||||
mAllAppsVisible = allAppsVisible;
|
||||
mAllAppsScrollAtTop = scrollAtTop;
|
||||
}
|
||||
|
||||
private boolean shouldScrollStart() {
|
||||
if (mAllAppsVisible && mDisplacement > mTouchSlop && mAllAppsScrollAtTop) {
|
||||
return true;
|
||||
}
|
||||
if (!mAllAppsVisible && mDisplacement < -mTouchSlop) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
switch (ev.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mDownMillis = ev.getDownTime();
|
||||
mDownY = ev.getY();
|
||||
mLastDisplacement = 0;
|
||||
mVelocity = 0;
|
||||
|
||||
if (mScrolling) {
|
||||
reportScrollStart(true /* recatch */);
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
mDisplacement = computeDisplacement(ev);
|
||||
mVelocity = computeVelocity(ev, mVelocity);
|
||||
|
||||
if (!mScrolling && shouldScrollStart()) {
|
||||
mScrolling = true;
|
||||
reportScrollStart(false /* recatch */);
|
||||
}
|
||||
if (mScrolling && mListener != null) {
|
||||
reportScroll();
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
case MotionEvent.ACTION_UP:
|
||||
// These are synthetic events and there is no need to update internal values.
|
||||
if (mScrolling && mListener != null) {
|
||||
reportScrollEnd();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
//TODO: add multi finger tracking by tracking active pointer.
|
||||
break;
|
||||
}
|
||||
// Do house keeping.
|
||||
mLastDisplacement = mDisplacement;
|
||||
|
||||
mLastY = ev.getY();
|
||||
mLastMillis = ev.getEventTime();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void finishedScrolling() {
|
||||
mScrolling = false;
|
||||
}
|
||||
|
||||
private boolean reportScrollStart(boolean recatch) {
|
||||
mListener.onScrollStart(!recatch);
|
||||
if (DBG) {
|
||||
Log.d(TAG, "onScrollStart recatch:" + recatch);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean reportScroll() {
|
||||
float delta = mDisplacement - mLastDisplacement;
|
||||
if (delta != 0) {
|
||||
if (DBG) {
|
||||
Log.d(TAG, String.format("onScroll disp=%.1f, velocity=%.1f",
|
||||
mDisplacement, mVelocity));
|
||||
}
|
||||
return mListener.onScroll(mDisplacement - (mSubtractSlop? mTouchSlop : 0), mVelocity);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void reportScrollEnd() {
|
||||
if (DBG) {
|
||||
Log.d(TAG, String.format("onScrolEnd disp=%.1f, velocity=%.1f",
|
||||
mDisplacement, mVelocity));
|
||||
}
|
||||
mListener.onScrollEnd(mVelocity, Math.abs(mVelocity) > RELEASE_VELOCITY_PX_MS);
|
||||
}
|
||||
/**
|
||||
* Computes the damped velocity using the two motion events and the previous velocity.
|
||||
*/
|
||||
private float computeVelocity(MotionEvent to, float previousVelocity) {
|
||||
float delta = computeDelta(to);
|
||||
|
||||
float deltaTimeMillis = to.getEventTime() - mLastMillis;
|
||||
float velocity = (deltaTimeMillis > 0) ? (delta / deltaTimeMillis) : 0;
|
||||
if (Math.abs(previousVelocity) < 0.001f) {
|
||||
return velocity;
|
||||
}
|
||||
|
||||
float alpha = computeDampeningFactor(deltaTimeMillis);
|
||||
return interpolate(previousVelocity, velocity, alpha);
|
||||
}
|
||||
|
||||
private float computeDisplacement(MotionEvent to) {
|
||||
return to.getY() - mDownY;
|
||||
}
|
||||
|
||||
private float computeDelta(MotionEvent to) {
|
||||
return to.getY() - mLastY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a time-dependent dampening factor using delta time.
|
||||
*/
|
||||
private static float computeDampeningFactor(float deltaTime) {
|
||||
return deltaTime / (SCROLL_VELOCITY_DAMPENING_RC + deltaTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the linear interpolation between two values
|
||||
*/
|
||||
private static float interpolate(float from, float to, float alpha) {
|
||||
return (1.0f - alpha) * from + alpha * to;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user