mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-15 16:48:20 +00:00
Merge "Predictive swipe: show extra app icons at bottom of All Apps's RecyclerViews" into tm-qpr-dev am: 77a388c79e
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/20956814 Change-Id: I4e2d1344d82163e4c44484f71c16534af7b4585a Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -37,4 +37,6 @@
|
||||
<item type="id" name="quick_settings_button" />
|
||||
<item type="id" name="notifications_button" />
|
||||
<item type="id" name="cache_entry_tag_id" />
|
||||
|
||||
<item type="id" name="saved_clip_children_tag_id" />
|
||||
</resources>
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
import androidx.annotation.Px;
|
||||
import androidx.core.view.accessibility.AccessibilityEventCompat;
|
||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
|
||||
import androidx.core.view.accessibility.AccessibilityRecordCompat;
|
||||
@@ -143,6 +144,19 @@ public class AllAppsGridAdapter<T extends Context & ActivityContext> extends
|
||||
cic.isSelected()));
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to extend all apps' RecyclerView's bottom by 5% of view height to ensure extra
|
||||
* roll(s) of app icons is rendered at the bottom, so that they can fill the bottom gap
|
||||
* created during predictive back's scale animation from all apps to home.
|
||||
*/
|
||||
@Override
|
||||
protected void calculateExtraLayoutSpace(RecyclerView.State state, int[] extraLayoutSpace) {
|
||||
super.calculateExtraLayoutSpace(state, extraLayoutSpace);
|
||||
@Px int extraSpacePx = (int) (getHeight()
|
||||
* (1 - AllAppsTransitionController.SWIPE_ALL_APPS_TO_HOME_MIN_SCALE) / 2);
|
||||
extraLayoutSpace[1] = Math.max(extraLayoutSpace[1], extraSpacePx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of rows before {@param adapterPosition}, including this position
|
||||
* which should not be counted towards the collection info.
|
||||
|
||||
@@ -32,14 +32,18 @@ import android.animation.ObjectAnimator;
|
||||
import android.util.FloatProperty;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.animation.Interpolator;
|
||||
|
||||
import androidx.annotation.FloatRange;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.AnimatedFloat;
|
||||
import com.android.launcher3.anim.AnimatorListeners;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
@@ -66,7 +70,7 @@ public class AllAppsTransitionController
|
||||
implements StateHandler<LauncherState>, OnDeviceProfileChangeListener {
|
||||
// This constant should match the second derivative of the animator interpolator.
|
||||
public static final float INTERP_COEFF = 1.7f;
|
||||
private static final float SWIPE_ALL_APPS_TO_HOME_MIN_SCALE = 0.9f;
|
||||
public static final float SWIPE_ALL_APPS_TO_HOME_MIN_SCALE = 0.9f;
|
||||
private static final int REVERT_SWIPE_ALL_APPS_TO_HOME_ANIMATION_DURATION_MS = 200;
|
||||
|
||||
public static final FloatProperty<AllAppsTransitionController> ALL_APPS_PROGRESS =
|
||||
@@ -168,6 +172,8 @@ public class AllAppsTransitionController
|
||||
|
||||
private boolean mIsTablet;
|
||||
|
||||
private boolean mHasScaleEffect;
|
||||
|
||||
public AllAppsTransitionController(Launcher l) {
|
||||
mLauncher = l;
|
||||
DeviceProfile dp = mLauncher.getDeviceProfile();
|
||||
@@ -276,8 +282,18 @@ public class AllAppsTransitionController
|
||||
rv.getScrollbar().setVisibility(scaleProgress < 1f ? View.INVISIBLE : View.VISIBLE);
|
||||
}
|
||||
|
||||
// TODO(b/264906511): We need to disable view clipping on all apps' parent views so
|
||||
// that the extra roll of app icons are displayed.
|
||||
// Disable view clipping from all apps' RecyclerView up to all apps view during scale
|
||||
// animation, and vice versa. The goal is to display extra roll(s) app icons (rendered in
|
||||
// {@link AppsGridLayoutManager#calculateExtraLayoutSpace}) during scale animation.
|
||||
boolean hasScaleEffect = scaleProgress < 1f;
|
||||
if (hasScaleEffect != mHasScaleEffect) {
|
||||
mHasScaleEffect = hasScaleEffect;
|
||||
if (mHasScaleEffect) {
|
||||
setClipChildrenOnViewTree(rv, mLauncher.getAppsView(), false);
|
||||
} else {
|
||||
restoreClipChildrenOnViewTree(rv, mLauncher.getAppsView());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void animateAllAppsToNoScale() {
|
||||
@@ -380,6 +396,79 @@ public class AllAppsTransitionController
|
||||
mShouldControlKeyboard = !mLauncher.getSearchConfig().isKeyboardSyncEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively call {@link ViewGroup#setClipChildren(boolean)} from {@link View} to ts parent
|
||||
* (direct or indirect) inclusive. This method will also save the old clipChildren value on each
|
||||
* view with {@link View#setTag(int, Object)}, which can be restored in
|
||||
* {@link #restoreClipChildrenOnViewTree(View, ViewParent)}.
|
||||
*
|
||||
* Note that if parent is null or not a parent of the view, this method will be applied all the
|
||||
* way to root view.
|
||||
*
|
||||
* @param v child view
|
||||
* @param parent direct or indirect parent of child view
|
||||
* @param clipChildren whether we should clip children
|
||||
*/
|
||||
private static void setClipChildrenOnViewTree(
|
||||
@Nullable View v,
|
||||
@Nullable ViewParent parent,
|
||||
boolean clipChildren) {
|
||||
if (v == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (v instanceof ViewGroup) {
|
||||
ViewGroup viewGroup = (ViewGroup) v;
|
||||
boolean oldClipChildren = viewGroup.getClipChildren();
|
||||
if (oldClipChildren != clipChildren) {
|
||||
v.setTag(R.id.saved_clip_children_tag_id, oldClipChildren);
|
||||
viewGroup.setClipChildren(clipChildren);
|
||||
}
|
||||
}
|
||||
|
||||
if (v == parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (v.getParent() instanceof View) {
|
||||
setClipChildrenOnViewTree((View) v.getParent(), parent, clipChildren);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively call {@link ViewGroup#setClipChildren(boolean)} to restore clip children value
|
||||
* set in {@link #setClipChildrenOnViewTree(View, ViewParent, boolean)} on view to its parent
|
||||
* (direct or indirect) inclusive.
|
||||
*
|
||||
* Note that if parent is null or not a parent of the view, this method will be applied all the
|
||||
* way to root view.
|
||||
*
|
||||
* @param v child view
|
||||
* @param parent direct or indirect parent of child view
|
||||
*/
|
||||
private static void restoreClipChildrenOnViewTree(
|
||||
@Nullable View v, @Nullable ViewParent parent) {
|
||||
if (v == null) {
|
||||
return;
|
||||
}
|
||||
if (v instanceof ViewGroup) {
|
||||
ViewGroup viewGroup = (ViewGroup) v;
|
||||
Object viewTag = viewGroup.getTag(R.id.saved_clip_children_tag_id);
|
||||
if (viewTag instanceof Boolean) {
|
||||
viewGroup.setClipChildren((boolean) viewTag);
|
||||
viewGroup.setTag(R.id.saved_clip_children_tag_id, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (v == parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (v.getParent() instanceof View) {
|
||||
restoreClipChildrenOnViewTree((View) v.getParent(), parent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the total scroll range but does not update the UI.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user