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
diff --git a/res/layout/widgets_list_row_header.xml b/res/layout/widgets_list_row_header.xml
index 3cdc2e8..35bea27 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 c61e3a4..984a274 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.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 @@
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 @@
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 @@
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 daa67a9..4c0e0d5 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 @@
* 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 @@
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 @@
@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 @@
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 @@
*/
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;
- }
- }
}