diff --git a/res/drawable/widgets_list_bottom_ripple.xml b/res/drawable/widgets_list_bottom_ripple.xml deleted file mode 100644 index c2debb1764..0000000000 --- a/res/drawable/widgets_list_bottom_ripple.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/res/drawable/widgets_list_middle_ripple.xml b/res/drawable/widgets_list_middle_ripple.xml deleted file mode 100644 index 83f96a08c2..0000000000 --- a/res/drawable/widgets_list_middle_ripple.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/res/drawable/widgets_list_single_item_ripple.xml b/res/drawable/widgets_list_single_item_ripple.xml deleted file mode 100644 index a4223a82c9..0000000000 --- a/res/drawable/widgets_list_single_item_ripple.xml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/res/drawable/widgets_list_top_ripple.xml b/res/drawable/widgets_list_top_ripple.xml deleted file mode 100644 index bc0876e40c..0000000000 --- a/res/drawable/widgets_list_top_ripple.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/res/layout/widgets_list_row_header.xml b/res/layout/widgets_list_row_header.xml index 8ab086c941..0bfa2b2a5e 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:background="@drawable/widgets_list_middle_ripple" android:layout_marginBottom="@dimen/widget_list_entry_bottom_margin" android:paddingVertical="@dimen/widget_list_header_view_vertical_padding" android:orientation="horizontal" diff --git a/res/layout/widgets_table_container.xml b/res/layout/widgets_table_container.xml index e63483ddd8..c6b70aa4aa 100644 --- a/res/layout/widgets_table_container.xml +++ b/res/layout/widgets_table_container.xml @@ -19,5 +19,4 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="16dp" - android:background="@drawable/widgets_list_middle_ripple" android:layout_marginBottom="@dimen/widget_list_entry_bottom_margin"/> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index d6a6f43803..f9d62a69de 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -131,6 +131,7 @@ 28dp 4dp + 0dp 20dp 2dp diff --git a/src/com/android/launcher3/widget/picker/WidgetsListDrawables.java b/src/com/android/launcher3/widget/picker/WidgetsListDrawables.java new file mode 100644 index 0000000000..b3bb544cd7 --- /dev/null +++ b/src/com/android/launcher3/widget/picker/WidgetsListDrawables.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.widget.picker; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.RippleDrawable; + +import com.android.launcher3.R; +import com.android.launcher3.util.Themes; + +/** Helper class for creating drawables to use as background for list elements. */ +final class WidgetsListDrawables { + + private WidgetsListDrawables() {} + + /** Creates a list background drawable with the specified radii. */ + static Drawable createListBackgroundDrawable( + Context context, + float topRadius, + float bottomRadius) { + GradientDrawable backgroundMask = new GradientDrawable(); + backgroundMask.setColor(context.getColorStateList(R.color.surface)); + backgroundMask.setShape(GradientDrawable.RECTANGLE); + + backgroundMask.setCornerRadii( + new float[]{ + topRadius, + topRadius, + topRadius, + topRadius, + bottomRadius, + bottomRadius, + bottomRadius, + bottomRadius + }); + + return new RippleDrawable( + /* color= */ ColorStateList.valueOf( + Themes.getAttrColor(context, android.R.attr.colorControlHighlight)), + /* content= */ backgroundMask, + /* mask= */ backgroundMask); + } + +} diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java index 41aa4378f0..fece359607 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java @@ -60,6 +60,9 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd @Nullable private Drawable mIconDrawable; private final int mIconSize; private final int mBottomMarginSize; + private final float mTopBottomCornerRadius; + private final float mMiddleCornerRadius; + private final float mJoinedCornerRadius; private ImageView mAppIcon; private TextView mTitle; @@ -87,6 +90,12 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd grid.iconSizePx); mBottomMarginSize = getResources().getDimensionPixelSize(R.dimen.widget_list_entry_bottom_margin); + mTopBottomCornerRadius = + getResources().getDimension(R.dimen.widget_list_top_bottom_corner_radius); + mMiddleCornerRadius = + getResources().getDimension(R.dimen.widget_list_content_corner_radius); + mJoinedCornerRadius = + getResources().getDimension(R.dimen.widget_list_content_joined_corner_radius); } @Override @@ -254,6 +263,20 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd verifyHighRes(); } + /** Updates the list to have a background drawable with the appropriate corner radii. */ + @UiThread + public void updateListBackground(boolean isFirst, boolean isLast, boolean isExpanded) { + float topRadius = isFirst ? mTopBottomCornerRadius : mMiddleCornerRadius; + float bottomRadius = isLast + ? mTopBottomCornerRadius + : isExpanded + ? mJoinedCornerRadius + : mMiddleCornerRadius; + setBackground( + WidgetsListDrawables.createListBackgroundDrawable( + getContext(), topRadius, bottomRadius)); + } + private void setTitles(WidgetsListSearchHeaderEntry entry) { mTitle.setText(entry.mPkgItem.title); diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java index e57f4d8811..22d6d227c4 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java @@ -52,15 +52,10 @@ public final class WidgetsListHeaderViewHolderBinder implements public void bindViewHolder(WidgetsListHeaderHolder viewHolder, WidgetsListHeaderEntry data, int position) { WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader; - if (mWidgetsListAdapter.getItemCount() == 1) { - widgetsListHeader.setBackgroundResource(R.drawable.widgets_list_single_item_ripple); - } else if (position == 0) { - widgetsListHeader.setBackgroundResource(R.drawable.widgets_list_top_ripple); - } else if (position == mWidgetsListAdapter.getItemCount() - 1) { - widgetsListHeader.setBackgroundResource(R.drawable.widgets_list_bottom_ripple); - } else { - widgetsListHeader.setBackgroundResource(R.drawable.widgets_list_middle_ripple); - } + widgetsListHeader.updateListBackground( + /* isFirst= */ position == 0, + /* isLast= */ position == mWidgetsListAdapter.getItemCount() - 1, + /* isExpanded= */ data.isWidgetListShown()); widgetsListHeader.applyFromItemInfoWithIcon(data); widgetsListHeader.setExpanded(data.isWidgetListShown()); widgetsListHeader.setOnExpandChangeListener(isExpanded -> diff --git a/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java index b98f5e18eb..d5e03a4fe0 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java @@ -53,15 +53,10 @@ public final class WidgetsListSearchHeaderViewHolderBinder implements public void bindViewHolder(WidgetsListSearchHeaderHolder viewHolder, WidgetsListSearchHeaderEntry data, int position) { WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader; - if (mWidgetsListAdapter.getItemCount() == 1) { - widgetsListHeader.setBackgroundResource(R.drawable.widgets_list_single_item_ripple); - } else if (position == 0) { - widgetsListHeader.setBackgroundResource(R.drawable.widgets_list_top_ripple); - } else if (position == mWidgetsListAdapter.getItemCount() - 1) { - widgetsListHeader.setBackgroundResource(R.drawable.widgets_list_bottom_ripple); - } else { - widgetsListHeader.setBackgroundResource(R.drawable.widgets_list_middle_ripple); - } + widgetsListHeader.updateListBackground( + /* isFirst= */ position == 0, + /* isLast= */ position == mWidgetsListAdapter.getItemCount() - 1, + /* isExpanded= */ data.isWidgetListShown()); widgetsListHeader.applyFromItemInfoWithIcon(data); widgetsListHeader.setExpanded(data.isWidgetListShown()); widgetsListHeader.setOnExpandChangeListener(isExpanded -> diff --git a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java index c3eda13c3f..8e310c5d83 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java @@ -16,6 +16,7 @@ package com.android.launcher3.widget.picker; import android.content.Context; +import android.content.res.Resources; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; @@ -51,6 +52,9 @@ public final class WidgetsListTableViewHolderBinder private final OnLongClickListener mIconLongClickListener; private final WidgetPreviewLoader mWidgetPreviewLoader; private final WidgetsListAdapter mWidgetsListAdapter; + private final float mTopBottomCornerRadius; + private final float mMiddleCornerRadius; + private final float mJoinedCornerRadius; private boolean mApplyBitmapDeferred = false; public WidgetsListTableViewHolderBinder( @@ -65,6 +69,13 @@ public final class WidgetsListTableViewHolderBinder mIconLongClickListener = iconLongClickListener; mWidgetPreviewLoader = widgetPreviewLoader; mWidgetsListAdapter = listAdapter; + Resources resources = context.getResources(); + mTopBottomCornerRadius = + resources.getDimension(R.dimen.widget_list_top_bottom_corner_radius); + mMiddleCornerRadius = + resources.getDimension(R.dimen.widget_list_content_corner_radius); + mJoinedCornerRadius = + resources.getDimension(R.dimen.widget_list_content_joined_corner_radius); } /** @@ -100,13 +111,14 @@ public final class WidgetsListTableViewHolderBinder entry.mWidgets.size(), table.getChildCount())); } - if (position == mWidgetsListAdapter.getItemCount() - 1) { - table.setBackgroundResource(R.drawable.widgets_list_bottom_ripple); - } else { - // WidgetsListContentEntry is never shown in position 0. There must be a header above - // it. - table.setBackgroundResource(R.drawable.widgets_list_middle_ripple); - } + // The content is always joined to an expanded header above. + float topRadius = mJoinedCornerRadius; + float bottomRadius = position == mWidgetsListAdapter.getItemCount() - 1 + ? mTopBottomCornerRadius + : mMiddleCornerRadius; + table.setBackgroundDrawable( + WidgetsListDrawables.createListBackgroundDrawable( + holder.itemView.getContext(), topRadius, bottomRadius)); List> widgetItemsTable = WidgetsTableUtils.groupWidgetItemsIntoTable(entry.mWidgets, mMaxSpansPerRow);