Merge "Add spacing between items as decorations instead of margins" into sc-dev
diff --git a/res/layout/widgets_list_row_header.xml b/res/layout/widgets_list_row_header.xml
index 0bfa2b2..3eaa7ea 100644
--- a/res/layout/widgets_list_row_header.xml
+++ b/res/layout/widgets_list_row_header.xml
@@ -20,7 +20,6 @@
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_marginHorizontal="16dp"
-    android:layout_marginBottom="@dimen/widget_list_entry_bottom_margin"
     android:paddingVertical="@dimen/widget_list_header_view_vertical_padding"
     android:orientation="horizontal"
     launcher:appIconSize="48dp">
diff --git a/res/layout/widgets_table_container.xml b/res/layout/widgets_table_container.xml
index 4f70a05..fac21fd 100644
--- a/res/layout/widgets_table_container.xml
+++ b/res/layout/widgets_table_container.xml
@@ -18,5 +18,4 @@
     android:id="@+id/widgets_table"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_marginHorizontal="16dp"
-    android:layout_marginBottom="@dimen/widget_list_entry_bottom_margin"/>
+    android:layout_marginHorizontal="16dp"/>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 251f04a..416179e 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -147,7 +147,7 @@
     <dimen name="widget_list_content_corner_radius">4dp</dimen>
 
     <dimen name="widget_list_header_view_vertical_padding">20dp</dimen>
-    <dimen name="widget_list_entry_bottom_margin">2dp</dimen>
+    <dimen name="widget_list_entry_spacing">2dp</dimen>
 
     <dimen name="widget_preview_shadow_blur">0.5dp</dimen>
     <dimen name="widget_preview_key_shadow_distance">1dp</dimen>
diff --git a/res/values/id.xml b/res/values/id.xml
index 1bd40ce..1709c59 100644
--- a/res/values/id.xml
+++ b/res/values/id.xml
@@ -16,6 +16,7 @@
 -->
 <resources>
     <item type="id" name="apps_list_view_work" />
+    <item type="id" name="tag_widget_entry" />
     <item type="id" name="view_type_widgets_list" />
     <item type="id" name="view_type_widgets_header" />
     <item type="id" name="view_type_widgets_search_header" />
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
index 5d9adf0..b668c90 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java
@@ -18,6 +18,7 @@
 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGETSTRAY_APP_EXPANDED;
 
 import android.content.Context;
+import android.graphics.Rect;
 import android.os.Process;
 import android.util.Log;
 import android.util.Size;
@@ -34,6 +35,7 @@
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
 import androidx.recyclerview.widget.RecyclerView.Adapter;
+import androidx.recyclerview.widget.RecyclerView.LayoutParams;
 import androidx.recyclerview.widget.RecyclerView.ViewHolder;
 
 import com.android.launcher3.BaseActivity;
@@ -107,7 +109,8 @@
     @Nullable private Predicate<WidgetsListBaseEntry> mFilter = null;
     @Nullable private RecyclerView mRecyclerView;
     @Nullable private PackageUserKey mPendingClickHeader;
-    private int mShortcutPreviewPadding;
+    private final int mShortcutPreviewPadding;
+    private final int mSpacingBetweenEntries;
 
     private final WidgetPreviewLoadedCallback mPreviewLoadedCallback =
             ignored -> updateVisibleEntries();
@@ -141,11 +144,28 @@
         mShortcutPreviewPadding =
                 2 * context.getResources()
                         .getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
+        mSpacingBetweenEntries =
+                context.getResources().getDimensionPixelSize(R.dimen.widget_list_entry_spacing);
     }
 
     @Override
     public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
         mRecyclerView = recyclerView;
+
+        mRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
+            @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 = ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
+                boolean isHeader =
+                        view.getTag(R.id.tag_widget_entry) instanceof WidgetsListBaseEntry.Header;
+                outRect.top += position > 0 && isHeader ? mSpacingBetweenEntries : 0;
+            }
+        });
     }
 
     @Override
@@ -329,7 +349,9 @@
     @Override
     public void onBindViewHolder(ViewHolder holder, int pos) {
         ViewHolderBinder viewHolderBinder = mViewHolderBinders.get(getItemViewType(pos));
+        WidgetsListBaseEntry entry = mVisibleEntries.get(pos);
         viewHolderBinder.bindViewHolder(holder, mVisibleEntries.get(pos), pos);
+        holder.itemView.setTag(R.id.tag_widget_entry, entry);
     }
 
     @Override
diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
index cdab964..ef2adbb 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java
@@ -30,7 +30,6 @@
 
 import androidx.annotation.Nullable;
 import androidx.annotation.UiThread;
-import androidx.recyclerview.widget.RecyclerView;
 
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.LauncherAppState;
@@ -59,7 +58,6 @@
     @Nullable private HandlerRunnable mIconLoadRequest;
     @Nullable private Drawable mIconDrawable;
     private final int mIconSize;
-    private final int mBottomMarginSize;
 
     private ImageView mAppIcon;
     private TextView mTitle;
@@ -86,8 +84,6 @@
                 R.styleable.WidgetsListRowHeader, defStyleAttr, /* defStyleRes= */ 0);
         mIconSize = a.getDimensionPixelSize(R.styleable.WidgetsListRowHeader_appIconSize,
                 grid.iconSizePx);
-        mBottomMarginSize =
-                getResources().getDimensionPixelSize(R.dimen.widget_list_entry_bottom_margin);
     }
 
     @Override
@@ -146,13 +142,6 @@
     public void setExpanded(boolean isExpanded) {
         this.mIsExpanded = isExpanded;
         mExpandToggle.setChecked(isExpanded);
-        if (getLayoutParams() instanceof RecyclerView.LayoutParams) {
-            int bottomMargin = isExpanded ? 0 : mBottomMarginSize;
-            RecyclerView.LayoutParams layoutParams =
-                    ((RecyclerView.LayoutParams) getLayoutParams());
-            layoutParams.bottomMargin = bottomMargin;
-            setLayoutParams(layoutParams);
-        }
     }
 
     /** Sets the {@link WidgetsListDrawableState} and refreshes the background drawable. */
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
index 3ee8b33..7671841 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java
@@ -52,7 +52,7 @@
     private HeaderViewDimensionsProvider mHeaderViewDimensionsProvider;
     private int mLastVisibleWidgetContentTableHeight = 0;
     private int mWidgetHeaderHeight = 0;
-    private final int mCollapsedHeaderBottomMarginSize;
+    private final int mSpacingBetweenEntries;
     @Nullable private OnContentChangeListener mOnContentChangeListener;
 
     public WidgetsRecyclerView(Context context) {
@@ -72,9 +72,9 @@
         ActivityContext activity = ActivityContext.lookupContext(getContext());
         DeviceProfile grid = activity.getDeviceProfile();
 
-        // The bottom margin used when the header is not expanded.
-        mCollapsedHeaderBottomMarginSize =
-                getResources().getDimensionPixelSize(R.dimen.widget_list_entry_bottom_margin);
+        // The spacing used between entries.
+        mSpacingBetweenEntries =
+                getResources().getDimensionPixelSize(R.dimen.widget_list_entry_spacing);
     }
 
     @Override
@@ -270,16 +270,16 @@
         if (untilIndex > mAdapter.getItems().size()) {
             untilIndex = mAdapter.getItems().size();
         }
-        int expandedHeaderPosition = mAdapter.getSelectedHeaderPosition().orElse(-1);
         int totalItemsHeight = 0;
         for (int i = 0; i < untilIndex; i++) {
             WidgetsListBaseEntry entry = mAdapter.getItems().get(i);
             if (entry instanceof WidgetsListHeaderEntry
                     || entry instanceof WidgetsListSearchHeaderEntry) {
                 totalItemsHeight += mWidgetHeaderHeight;
-                if (expandedHeaderPosition != i) {
-                    // If the header is collapsed, include the bottom margin it will use.
-                    totalItemsHeight += mCollapsedHeaderBottomMarginSize;
+                if (i > 0) {
+                    // Each header contains the spacing between entries as top decoration, except
+                    // the first one.
+                    totalItemsHeight += mSpacingBetweenEntries;
                 }
             } else if (entry instanceof WidgetsListContentEntry) {
                 totalItemsHeight += mLastVisibleWidgetContentTableHeight;