Loading res/values/id.xml +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ <item type="id" name="cache_entry_tag_id" /> <item type="id" name="saved_clip_children_tag_id" /> <item type="id" name="saved_clip_to_padding_tag_id" /> <item type="id" name="saved_floating_widget_foreground" /> <item type="id" name="saved_floating_widget_background" /> Loading src/com/android/launcher3/Utilities.java +132 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,8 @@ import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewParent; import android.view.animation.Interpolator; import androidx.annotation.ChecksSdkIntAtLeast; Loading Loading @@ -772,6 +774,136 @@ public final class Utilities { )); } /** * 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 */ public 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 */ public 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); } } /** * Similar to {@link #setClipChildrenOnViewTree(View, ViewParent, boolean)} but is calling * {@link ViewGroup#setClipToPadding}. */ public static void setClipToPaddingOnViewTree( @Nullable View v, @Nullable ViewParent parent, boolean clipToPadding) { if (v == null) { return; } if (v instanceof ViewGroup) { ViewGroup viewGroup = (ViewGroup) v; boolean oldClipToPadding = viewGroup.getClipToPadding(); if (oldClipToPadding != clipToPadding) { v.setTag(R.id.saved_clip_to_padding_tag_id, oldClipToPadding); viewGroup.setClipToPadding(clipToPadding); } } if (v == parent) { return; } if (v.getParent() instanceof View) { setClipToPaddingOnViewTree((View) v.getParent(), parent, clipToPadding); } } /** * Similar to {@link #restoreClipChildrenOnViewTree(View, ViewParent)} but is calling * {@link ViewGroup#setClipToPadding}. */ public static void restoreClipToPaddingOnViewTree( @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_to_padding_tag_id); if (viewTag instanceof Boolean) { viewGroup.setClipToPadding((boolean) viewTag); viewGroup.setTag(R.id.saved_clip_to_padding_tag_id, null); } } if (v == parent) { return; } if (v.getParent() instanceof View) { restoreClipToPaddingOnViewTree((View) v.getParent(), parent); } } /** * Translates the {@code targetView} so that it overlaps with {@code exclusionBounds} as little * as possible, while remaining within {@code inclusionBounds}. Loading src/com/android/launcher3/allapps/AllAppsTransitionController.java +2 −76 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT; import static com.android.launcher3.LauncherState.BACKGROUND_APP; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.Utilities.restoreClipChildrenOnViewTree; import static com.android.launcher3.Utilities.setClipChildrenOnViewTree; import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER; import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_BOTTOM_SHEET_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE; Loading @@ -38,12 +40,9 @@ import android.animation.ValueAnimator; 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.app.animation.Interpolators; import com.android.launcher3.DeviceProfile; Loading Loading @@ -422,79 +421,6 @@ public class AllAppsTransitionController mAppsView, VIEW_TRANSLATE_Y, APPS_VIEW_INDEX_COUNT, Float::sum); } /** * 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. */ Loading src/com/android/launcher3/views/AbstractSlideInView.java +1 −2 Original line number Diff line number Diff line Loading @@ -347,8 +347,7 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext> /** Return extra space revealed during predictive back animation. */ @Px protected int getBottomOffsetPx() { final int height = getMeasuredHeight(); return (int) ((height / PREDICTIVE_BACK_MIN_SCALE - height) / 2); return (int) (getMeasuredHeight() * (1 - PREDICTIVE_BACK_MIN_SCALE)); } /** Loading src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java +33 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,10 @@ package com.android.launcher3.widget.picker; import static com.android.launcher3.Flags.enableCategorizedWidgetSuggestions; import static com.android.launcher3.Flags.enableUnfoldedTwoPanePicker; import static com.android.launcher3.Utilities.restoreClipChildrenOnViewTree; import static com.android.launcher3.Utilities.restoreClipToPaddingOnViewTree; import static com.android.launcher3.Utilities.setClipChildrenOnViewTree; import static com.android.launcher3.Utilities.setClipToPaddingOnViewTree; import android.content.Context; import android.graphics.Outline; Loading @@ -27,6 +31,7 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewOutlineProvider; import android.view.ViewParent; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.ScrollView; Loading Loading @@ -60,10 +65,13 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet { private FrameLayout mSuggestedWidgetsContainer; private WidgetsListHeader mSuggestedWidgetsHeader; private PackageUserKey mSuggestedWidgetsPackageUserKey; private View mPrimaryWidgetListView; private LinearLayout mRightPane; private ScrollView mRightPaneScrollView; private WidgetsListTableViewHolderBinder mWidgetsListTableViewHolderBinder; private boolean mOldIsBackSwipeProgressing; private int mActivePage = -1; private PackageUserKey mSelectedHeader; Loading Loading @@ -124,6 +132,12 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet { mRightPane.setOutlineProvider(mViewOutlineProviderRightPane); mRightPaneScrollView = mContent.findViewById(R.id.right_pane_scroll_view); mRightPaneScrollView.setOverScrollMode(View.OVER_SCROLL_NEVER); mRightPaneScrollView.setOutlineProvider(mViewOutlineProvider); mRightPaneScrollView.setClipToOutline(true); mPrimaryWidgetListView = findViewById(R.id.primary_widgets_list_view); mPrimaryWidgetListView.setOutlineProvider(mViewOutlineProvider); mPrimaryWidgetListView.setClipToOutline(true); onRecommendedWidgetsBound(); onWidgetsBound(); Loading @@ -133,6 +147,25 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet { mFastScroller.setVisibility(GONE); } @Override protected void onScaleProgressChanged() { super.onScaleProgressChanged(); boolean isBackSwipeProgressing = mSlideInViewScale.value > 0; if (isBackSwipeProgressing == mOldIsBackSwipeProgressing) { return; } mOldIsBackSwipeProgressing = isBackSwipeProgressing; if (isBackSwipeProgressing) { setClipChildrenOnViewTree(mPrimaryWidgetListView, (ViewParent) mContent, false); setClipChildrenOnViewTree(mRightPaneScrollView, (ViewParent) mContent, false); setClipToPaddingOnViewTree(mRightPaneScrollView, (ViewParent) mContent, false); } else { restoreClipChildrenOnViewTree(mPrimaryWidgetListView, mContent); restoreClipChildrenOnViewTree(mRightPaneScrollView, mContent); restoreClipToPaddingOnViewTree(mRightPaneScrollView, mContent); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); Loading Loading
res/values/id.xml +1 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ <item type="id" name="cache_entry_tag_id" /> <item type="id" name="saved_clip_children_tag_id" /> <item type="id" name="saved_clip_to_padding_tag_id" /> <item type="id" name="saved_floating_widget_foreground" /> <item type="id" name="saved_floating_widget_background" /> Loading
src/com/android/launcher3/Utilities.java +132 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,8 @@ import android.util.TypedValue; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewParent; import android.view.animation.Interpolator; import androidx.annotation.ChecksSdkIntAtLeast; Loading Loading @@ -772,6 +774,136 @@ public final class Utilities { )); } /** * 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 */ public 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 */ public 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); } } /** * Similar to {@link #setClipChildrenOnViewTree(View, ViewParent, boolean)} but is calling * {@link ViewGroup#setClipToPadding}. */ public static void setClipToPaddingOnViewTree( @Nullable View v, @Nullable ViewParent parent, boolean clipToPadding) { if (v == null) { return; } if (v instanceof ViewGroup) { ViewGroup viewGroup = (ViewGroup) v; boolean oldClipToPadding = viewGroup.getClipToPadding(); if (oldClipToPadding != clipToPadding) { v.setTag(R.id.saved_clip_to_padding_tag_id, oldClipToPadding); viewGroup.setClipToPadding(clipToPadding); } } if (v == parent) { return; } if (v.getParent() instanceof View) { setClipToPaddingOnViewTree((View) v.getParent(), parent, clipToPadding); } } /** * Similar to {@link #restoreClipChildrenOnViewTree(View, ViewParent)} but is calling * {@link ViewGroup#setClipToPadding}. */ public static void restoreClipToPaddingOnViewTree( @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_to_padding_tag_id); if (viewTag instanceof Boolean) { viewGroup.setClipToPadding((boolean) viewTag); viewGroup.setTag(R.id.saved_clip_to_padding_tag_id, null); } } if (v == parent) { return; } if (v.getParent() instanceof View) { restoreClipToPaddingOnViewTree((View) v.getParent(), parent); } } /** * Translates the {@code targetView} so that it overlaps with {@code exclusionBounds} as little * as possible, while remaining within {@code inclusionBounds}. Loading
src/com/android/launcher3/allapps/AllAppsTransitionController.java +2 −76 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.ALL_APPS_CONTENT; import static com.android.launcher3.LauncherState.BACKGROUND_APP; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.Utilities.restoreClipChildrenOnViewTree; import static com.android.launcher3.Utilities.setClipChildrenOnViewTree; import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER; import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_BOTTOM_SHEET_FADE; import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE; Loading @@ -38,12 +40,9 @@ import android.animation.ValueAnimator; 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.app.animation.Interpolators; import com.android.launcher3.DeviceProfile; Loading Loading @@ -422,79 +421,6 @@ public class AllAppsTransitionController mAppsView, VIEW_TRANSLATE_Y, APPS_VIEW_INDEX_COUNT, Float::sum); } /** * 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. */ Loading
src/com/android/launcher3/views/AbstractSlideInView.java +1 −2 Original line number Diff line number Diff line Loading @@ -347,8 +347,7 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext> /** Return extra space revealed during predictive back animation. */ @Px protected int getBottomOffsetPx() { final int height = getMeasuredHeight(); return (int) ((height / PREDICTIVE_BACK_MIN_SCALE - height) / 2); return (int) (getMeasuredHeight() * (1 - PREDICTIVE_BACK_MIN_SCALE)); } /** Loading
src/com/android/launcher3/widget/picker/WidgetsTwoPaneSheet.java +33 −0 Original line number Diff line number Diff line Loading @@ -17,6 +17,10 @@ package com.android.launcher3.widget.picker; import static com.android.launcher3.Flags.enableCategorizedWidgetSuggestions; import static com.android.launcher3.Flags.enableUnfoldedTwoPanePicker; import static com.android.launcher3.Utilities.restoreClipChildrenOnViewTree; import static com.android.launcher3.Utilities.restoreClipToPaddingOnViewTree; import static com.android.launcher3.Utilities.setClipChildrenOnViewTree; import static com.android.launcher3.Utilities.setClipToPaddingOnViewTree; import android.content.Context; import android.graphics.Outline; Loading @@ -27,6 +31,7 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewOutlineProvider; import android.view.ViewParent; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.ScrollView; Loading Loading @@ -60,10 +65,13 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet { private FrameLayout mSuggestedWidgetsContainer; private WidgetsListHeader mSuggestedWidgetsHeader; private PackageUserKey mSuggestedWidgetsPackageUserKey; private View mPrimaryWidgetListView; private LinearLayout mRightPane; private ScrollView mRightPaneScrollView; private WidgetsListTableViewHolderBinder mWidgetsListTableViewHolderBinder; private boolean mOldIsBackSwipeProgressing; private int mActivePage = -1; private PackageUserKey mSelectedHeader; Loading Loading @@ -124,6 +132,12 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet { mRightPane.setOutlineProvider(mViewOutlineProviderRightPane); mRightPaneScrollView = mContent.findViewById(R.id.right_pane_scroll_view); mRightPaneScrollView.setOverScrollMode(View.OVER_SCROLL_NEVER); mRightPaneScrollView.setOutlineProvider(mViewOutlineProvider); mRightPaneScrollView.setClipToOutline(true); mPrimaryWidgetListView = findViewById(R.id.primary_widgets_list_view); mPrimaryWidgetListView.setOutlineProvider(mViewOutlineProvider); mPrimaryWidgetListView.setClipToOutline(true); onRecommendedWidgetsBound(); onWidgetsBound(); Loading @@ -133,6 +147,25 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet { mFastScroller.setVisibility(GONE); } @Override protected void onScaleProgressChanged() { super.onScaleProgressChanged(); boolean isBackSwipeProgressing = mSlideInViewScale.value > 0; if (isBackSwipeProgressing == mOldIsBackSwipeProgressing) { return; } mOldIsBackSwipeProgressing = isBackSwipeProgressing; if (isBackSwipeProgressing) { setClipChildrenOnViewTree(mPrimaryWidgetListView, (ViewParent) mContent, false); setClipChildrenOnViewTree(mRightPaneScrollView, (ViewParent) mContent, false); setClipToPaddingOnViewTree(mRightPaneScrollView, (ViewParent) mContent, false); } else { restoreClipChildrenOnViewTree(mPrimaryWidgetListView, mContent); restoreClipChildrenOnViewTree(mRightPaneScrollView, mContent); restoreClipToPaddingOnViewTree(mRightPaneScrollView, mContent); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); Loading