From ed681548fcc3519ed4c28d758a2a2cbbc22fd2db Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 23 Jun 2022 12:00:57 -0700 Subject: [PATCH] Moving widget padding to drawable instead of using itemDecorator ItemDecorator uses item position which is not stable during animations. Moving it to the background allows the padding to be stable Bug: 236961658 Test: Verified that the app doesn't crash. Change-Id: Ied12077de4097e827c5c4157f5196346a301f185 --- res/layout/widgets_list_row_header.xml | 1 - .../picker/WidgetsListDrawableFactory.java | 11 ++++- .../widget/picker/WidgetsRecyclerView.java | 41 +------------------ 3 files changed, 12 insertions(+), 41 deletions(-) diff --git a/res/layout/widgets_list_row_header.xml b/res/layout/widgets_list_row_header.xml index 3cdc2e844b..35bea279c0 100644 --- a/res/layout/widgets_list_row_header.xml +++ b/res/layout/widgets_list_row_header.xml @@ -19,7 +19,6 @@ android:id="@+id/widgets_list_header" android:layout_width="match_parent" android:layout_height="wrap_content" - android:paddingVertical="@dimen/widget_list_header_view_vertical_padding" android:orientation="horizontal" android:importantForAccessibility="yes" android:focusable="true" diff --git a/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java b/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java index c61e3a4349..984a2741e7 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java @@ -27,6 +27,7 @@ import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.InsetDrawable; import android.graphics.drawable.RippleDrawable; import android.graphics.drawable.StateListDrawable; @@ -40,6 +41,8 @@ final class WidgetsListDrawableFactory { private final float mMiddleCornerRadius; private final ColorStateList mSurfaceColor; private final ColorStateList mRippleColor; + private final int mVerticalPadding; + private final int mHeaderMargin; WidgetsListDrawableFactory(Context context) { Resources res = context.getResources(); @@ -48,6 +51,9 @@ final class WidgetsListDrawableFactory { mSurfaceColor = context.getColorStateList(R.color.surface); mRippleColor = ColorStateList.valueOf( Themes.getAttrColor(context, android.R.attr.colorControlHighlight)); + mVerticalPadding = + res.getDimensionPixelSize(R.dimen.widget_list_header_view_vertical_padding); + mHeaderMargin = res.getDimensionPixelSize(R.dimen.widget_list_entry_spacing); } /** @@ -74,7 +80,10 @@ final class WidgetsListDrawableFactory { stateList.addState( LAST.mStateSet, createRoundedRectDrawable(mMiddleCornerRadius, mTopBottomCornerRadius)); - return new RippleDrawable(mRippleColor, /* content= */ stateList, /* mask= */ stateList); + RippleDrawable ripple = + new RippleDrawable(mRippleColor, /* content= */ stateList, /* mask= */ stateList); + ripple.setPadding(0, mVerticalPadding, 0, mVerticalPadding); + return new InsetDrawable(ripple, 0, mHeaderMargin, 0, 0); } /** diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java index daa67a973c..4c0e0d595f 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java +++ b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java @@ -16,18 +16,12 @@ package com.android.launcher3.widget.picker; -import static com.android.launcher3.widget.picker.WidgetsListAdapter.VIEW_TYPE_WIDGETS_HEADER; -import static com.android.launcher3.widget.picker.WidgetsListAdapter.VIEW_TYPE_WIDGETS_SEARCH_HEADER; - import android.content.Context; import android.graphics.Point; -import android.graphics.Rect; import android.util.AttributeSet; import android.util.SparseIntArray; import android.view.MotionEvent; -import android.view.View; -import androidx.annotation.NonNull; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener; @@ -55,7 +49,6 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte * VIEW_TYPE_WIDGETS_LIST is not visible on the screen. */ private final SparseIntArray mCachedSizes = new SparseIntArray(); - private final SpacingDecoration mSpacingDecoration; public WidgetsRecyclerView(Context context) { this(context, null); @@ -70,9 +63,6 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte super(context, attrs, defStyleAttr); mScrollbarTop = getResources().getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin); addOnItemTouchListener(this); - - mSpacingDecoration = new SpacingDecoration(context); - addItemDecoration(mSpacingDecoration); } @Override @@ -183,7 +173,7 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte @Override protected int getItemsHeight(int untilIndex) { // Initialize cache - int childCount = getChildCount(); + int childCount = Math.min(getChildCount(), getAdapter().getItemCount()); int startPosition; if (childCount > 0 && ((startPosition = getChildAdapterPosition(getChildAt(0))) != NO_POSITION)) { @@ -200,7 +190,7 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte int totalItemsHeight = 0; for (int i = 0; i < untilIndex; i++) { int type = mAdapter.getItemViewType(i); - totalItemsHeight += mCachedSizes.get(type) + mSpacingDecoration.getSpacing(i, type); + totalItemsHeight += mCachedSizes.get(type); } return totalItemsHeight; } @@ -216,31 +206,4 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte */ int getHeaderViewHeight(); } - - private static class SpacingDecoration extends RecyclerView.ItemDecoration { - - private final int mSpacingBetweenEntries; - - SpacingDecoration(@NonNull Context context) { - mSpacingBetweenEntries = - context.getResources().getDimensionPixelSize(R.dimen.widget_list_entry_spacing); - } - - @Override - public void getItemOffsets( - @NonNull Rect outRect, - @NonNull View view, - @NonNull RecyclerView parent, - @NonNull RecyclerView.State state) { - super.getItemOffsets(outRect, view, parent, state); - int position = parent.getChildAdapterPosition(view); - outRect.top += getSpacing(position, parent.getAdapter().getItemViewType(position)); - } - - public int getSpacing(int position, int type) { - boolean isHeader = type == VIEW_TYPE_WIDGETS_SEARCH_HEADER - || type == VIEW_TYPE_WIDGETS_HEADER; - return position > 0 && isHeader ? mSpacingBetweenEntries : 0; - } - } }