diff --git a/res/layout/widgets_table_container.xml b/res/layout/widgets_table_container.xml index c6b70aa4aa..4f70a05374 100644 --- a/res/layout/widgets_table_container.xml +++ b/res/layout/widgets_table_container.xml @@ -13,7 +13,7 @@ See the License for the specific language governing permissions and limitations under the License. --> -28dp 4dp - 0dp 20dp 2dp diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java index 84a03d572c..4e2a508394 100644 --- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java +++ b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinderTest.java @@ -107,7 +107,10 @@ public final class WidgetsListHeaderViewHolderBinderTest { /* iconClickListener= */ view -> {}, /* iconLongClickListener= */ view -> false); mViewHolderBinder = new WidgetsListHeaderViewHolderBinder( - LayoutInflater.from(mTestActivity), mOnHeaderClickListener, widgetsListAdapter); + LayoutInflater.from(mTestActivity), + mOnHeaderClickListener, + new WidgetsListDrawableFactory(mTestActivity), + widgetsListAdapter); } @After diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java index 075c58db6b..d6aea554f2 100644 --- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java +++ b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinderTest.java @@ -107,7 +107,10 @@ public final class WidgetsListSearchHeaderViewHolderBinderTest { /* iconClickListener= */ view -> {}, /* iconLongClickListener= */ view -> false); mViewHolderBinder = new WidgetsListSearchHeaderViewHolderBinder( - LayoutInflater.from(mTestActivity), mOnHeaderClickListener, widgetsListAdapter); + LayoutInflater.from(mTestActivity), + mOnHeaderClickListener, + new WidgetsListDrawableFactory(mTestActivity), + widgetsListAdapter); } @After diff --git a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java index 0c6e71711d..2f1326fdc0 100644 --- a/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java +++ b/robolectric_tests/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinderTest.java @@ -118,6 +118,7 @@ public final class WidgetsListTableViewHolderBinderTest { mOnIconClickListener, mOnLongClickListener, mWidgetPreviewLoader, + new WidgetsListDrawableFactory(mTestActivity), widgetsListAdapter); } diff --git a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java index e89aea7507..6863c60a37 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListAdapter.java @@ -103,18 +103,25 @@ public class WidgetsListAdapter extends Adapter implements OnHeaderC OnClickListener iconClickListener, OnLongClickListener iconLongClickListener) { mLauncher = Launcher.getLauncher(context); mDiffReporter = new WidgetsDiffReporter(iconCache, this); + WidgetsListDrawableFactory listDrawableFactory = new WidgetsListDrawableFactory(context); mWidgetsListTableViewHolderBinder = new WidgetsListTableViewHolderBinder(context, layoutInflater, iconClickListener, iconLongClickListener, - widgetPreviewLoader, /* listAdapter= */ this); + widgetPreviewLoader, listDrawableFactory, /* listAdapter= */ this); mViewHolderBinders.put(VIEW_TYPE_WIDGETS_LIST, mWidgetsListTableViewHolderBinder); mViewHolderBinders.put( VIEW_TYPE_WIDGETS_HEADER, new WidgetsListHeaderViewHolderBinder( - layoutInflater, /* onHeaderClickListener= */this, /* listAdapter= */ this)); + layoutInflater, + /* onHeaderClickListener= */ this, + listDrawableFactory, + /* listAdapter= */ this)); mViewHolderBinders.put( VIEW_TYPE_WIDGETS_SEARCH_HEADER, new WidgetsListSearchHeaderViewHolderBinder( - layoutInflater, /*onHeaderClickListener=*/ this, /* listAdapter= */ this)); + layoutInflater, + /* onHeaderClickListener= */ this, + listDrawableFactory, + /* listAdapter= */ this)); } @Override diff --git a/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java b/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java new file mode 100644 index 0000000000..c61e3a4349 --- /dev/null +++ b/src/com/android/launcher3/widget/picker/WidgetsListDrawableFactory.java @@ -0,0 +1,113 @@ +/* + * 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 static com.android.launcher3.widget.picker.WidgetsListDrawableState.FIRST; +import static com.android.launcher3.widget.picker.WidgetsListDrawableState.FIRST_EXPANDED; +import static com.android.launcher3.widget.picker.WidgetsListDrawableState.LAST; +import static com.android.launcher3.widget.picker.WidgetsListDrawableState.MIDDLE; +import static com.android.launcher3.widget.picker.WidgetsListDrawableState.MIDDLE_EXPANDED; +import static com.android.launcher3.widget.picker.WidgetsListDrawableState.SINGLE; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.RippleDrawable; +import android.graphics.drawable.StateListDrawable; + +import com.android.launcher3.R; +import com.android.launcher3.util.Themes; + +/** Factory for creating drawables to use as background for list elements. */ +final class WidgetsListDrawableFactory { + + private final float mTopBottomCornerRadius; + private final float mMiddleCornerRadius; + private final ColorStateList mSurfaceColor; + private final ColorStateList mRippleColor; + + WidgetsListDrawableFactory(Context context) { + Resources res = context.getResources(); + mTopBottomCornerRadius = res.getDimension(R.dimen.widget_list_top_bottom_corner_radius); + mMiddleCornerRadius = res.getDimension(R.dimen.widget_list_content_corner_radius); + mSurfaceColor = context.getColorStateList(R.color.surface); + mRippleColor = ColorStateList.valueOf( + Themes.getAttrColor(context, android.R.attr.colorControlHighlight)); + } + + /** + * Creates a drawable for widget header list items. This drawable supports all positions + * in {@link WidgetsListDrawableState}. + */ + Drawable createHeaderBackgroundDrawable() { + StateListDrawable stateList = new StateListDrawable(); + stateList.addState( + SINGLE.mStateSet, + createRoundedRectDrawable(mTopBottomCornerRadius, mTopBottomCornerRadius)); + stateList.addState( + FIRST_EXPANDED.mStateSet, + createRoundedRectDrawable(mTopBottomCornerRadius, 0)); + stateList.addState( + FIRST.mStateSet, + createRoundedRectDrawable(mTopBottomCornerRadius, mMiddleCornerRadius)); + stateList.addState( + MIDDLE_EXPANDED.mStateSet, + createRoundedRectDrawable(mMiddleCornerRadius, 0)); + stateList.addState( + MIDDLE.mStateSet, + createRoundedRectDrawable(mMiddleCornerRadius, mMiddleCornerRadius)); + stateList.addState( + LAST.mStateSet, + createRoundedRectDrawable(mMiddleCornerRadius, mTopBottomCornerRadius)); + return new RippleDrawable(mRippleColor, /* content= */ stateList, /* mask= */ stateList); + } + + /** + * Creates a drawable for widget content list items. This state list supports the middle and + * last states. + */ + Drawable createContentBackgroundDrawable() { + StateListDrawable stateList = new StateListDrawable(); + stateList.addState( + MIDDLE.mStateSet, + createRoundedRectDrawable(0, mMiddleCornerRadius)); + stateList.addState( + LAST.mStateSet, + createRoundedRectDrawable(0, mTopBottomCornerRadius)); + return new RippleDrawable(mRippleColor, /* content= */ stateList, /* mask= */ stateList); + } + + /** Creates a rounded-rect drawable with the specified radii. */ + private Drawable createRoundedRectDrawable(float topRadius, float bottomRadius) { + GradientDrawable backgroundMask = new GradientDrawable(); + backgroundMask.setColor(mSurfaceColor); + backgroundMask.setShape(GradientDrawable.RECTANGLE); + backgroundMask.setCornerRadii( + new float[]{ + topRadius, + topRadius, + topRadius, + topRadius, + bottomRadius, + bottomRadius, + bottomRadius, + bottomRadius + }); + return backgroundMask; + } +} diff --git a/src/com/android/launcher3/widget/picker/WidgetsListDrawableState.java b/src/com/android/launcher3/widget/picker/WidgetsListDrawableState.java new file mode 100644 index 0000000000..94f292beb2 --- /dev/null +++ b/src/com/android/launcher3/widget/picker/WidgetsListDrawableState.java @@ -0,0 +1,44 @@ +/* + * 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; + +/** + * Different possible list position states for an item in the widgets list to have. Note that only + * headers use the expanded state. + */ +enum WidgetsListDrawableState { + FIRST(new int[]{android.R.attr.state_first}), + FIRST_EXPANDED(new int[]{android.R.attr.state_first, android.R.attr.state_expanded}), + MIDDLE(new int[]{android.R.attr.state_middle}), + MIDDLE_EXPANDED(new int[]{android.R.attr.state_middle, android.R.attr.state_expanded}), + LAST(new int[]{android.R.attr.state_last}), + SINGLE(new int[]{android.R.attr.state_single}); + + final int[] mStateSet; + + WidgetsListDrawableState(int[] stateSet) { + mStateSet = stateSet; + } + + static WidgetsListDrawableState obtain(boolean isFirst, boolean isLast, boolean isExpanded) { + if (isFirst && isLast) return SINGLE; + if (isFirst && isExpanded) return FIRST_EXPANDED; + if (isFirst) return FIRST; + if (isLast) return LAST; + if (isExpanded) return MIDDLE_EXPANDED; + return MIDDLE; + } +} diff --git a/src/com/android/launcher3/widget/picker/WidgetsListDrawables.java b/src/com/android/launcher3/widget/picker/WidgetsListDrawables.java deleted file mode 100644 index b3bb544cd7..0000000000 --- a/src/com/android/launcher3/widget/picker/WidgetsListDrawables.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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 fece359607..cdab964279 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListHeader.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListHeader.java @@ -60,9 +60,6 @@ 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; @@ -70,6 +67,7 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd private CheckBox mExpandToggle; private boolean mIsExpanded = false; + @Nullable private WidgetsListDrawableState mListDrawableState; public WidgetsListHeader(Context context) { this(context, /* attrs= */ null); @@ -90,12 +88,6 @@ 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 @@ -163,6 +155,14 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd } } + /** Sets the {@link WidgetsListDrawableState} and refreshes the background drawable. */ + @UiThread + public void setListDrawableState(WidgetsListDrawableState state) { + if (state == mListDrawableState) return; + this.mListDrawableState = state; + refreshDrawableState(); + } + /** Apply app icon, labels and tag using a generic {@link WidgetsListHeaderEntry}. */ @UiThread public void applyFromItemInfoWithIcon(WidgetsListHeaderEntry entry) { @@ -263,20 +263,6 @@ 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); @@ -300,6 +286,17 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd } } + @Override + protected int[] onCreateDrawableState(int extraSpace) { + if (mListDrawableState == null) return super.onCreateDrawableState(extraSpace); + // Augment the state set from the super implementation with the custom states from + // mListDrawableState. + int[] drawableState = + super.onCreateDrawableState(extraSpace + mListDrawableState.mStateSet.length); + mergeDrawableStates(drawableState, mListDrawableState.mStateSet); + return drawableState; + } + /** Verifies that the current icon is high-res otherwise posts a request to load the icon. */ public void verifyHighRes() { if (mIconLoadRequest != null) { diff --git a/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java index 22d6d227c4..2f8f1bacfc 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListHeaderViewHolderBinder.java @@ -30,13 +30,16 @@ public final class WidgetsListHeaderViewHolderBinder implements ViewHolderBinder { private final LayoutInflater mLayoutInflater; private final OnHeaderClickListener mOnHeaderClickListener; + private final WidgetsListDrawableFactory mListDrawableFactory; private final WidgetsListAdapter mWidgetsListAdapter; public WidgetsListHeaderViewHolderBinder(LayoutInflater layoutInflater, OnHeaderClickListener onHeaderClickListener, + WidgetsListDrawableFactory listDrawableFactory, WidgetsListAdapter listAdapter) { mLayoutInflater = layoutInflater; mOnHeaderClickListener = onHeaderClickListener; + mListDrawableFactory = listDrawableFactory; mWidgetsListAdapter = listAdapter; } @@ -44,7 +47,7 @@ public final class WidgetsListHeaderViewHolderBinder implements public WidgetsListHeaderHolder newViewHolder(ViewGroup parent) { WidgetsListHeader header = (WidgetsListHeader) mLayoutInflater.inflate( R.layout.widgets_list_row_header, parent, false); - + header.setBackground(mListDrawableFactory.createHeaderBackgroundDrawable()); return new WidgetsListHeaderHolder(header); } @@ -52,12 +55,13 @@ public final class WidgetsListHeaderViewHolderBinder implements public void bindViewHolder(WidgetsListHeaderHolder viewHolder, WidgetsListHeaderEntry data, int position) { WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader; - widgetsListHeader.updateListBackground( - /* isFirst= */ position == 0, - /* isLast= */ position == mWidgetsListAdapter.getItemCount() - 1, - /* isExpanded= */ data.isWidgetListShown()); widgetsListHeader.applyFromItemInfoWithIcon(data); widgetsListHeader.setExpanded(data.isWidgetListShown()); + widgetsListHeader.setListDrawableState( + WidgetsListDrawableState.obtain( + /* isFirst= */ position == 0, + /* isLast= */ position == mWidgetsListAdapter.getItemCount() - 1, + /* isExpanded= */ data.isWidgetListShown())); widgetsListHeader.setOnExpandChangeListener(isExpanded -> mOnHeaderClickListener.onHeaderClicked( isExpanded, diff --git a/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java index d5e03a4fe0..31dd9ee0ae 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListSearchHeaderViewHolderBinder.java @@ -31,13 +31,16 @@ public final class WidgetsListSearchHeaderViewHolderBinder implements ViewHolderBinder { private final LayoutInflater mLayoutInflater; private final OnHeaderClickListener mOnHeaderClickListener; + private final WidgetsListDrawableFactory mListDrawableFactory; private final WidgetsListAdapter mWidgetsListAdapter; public WidgetsListSearchHeaderViewHolderBinder(LayoutInflater layoutInflater, OnHeaderClickListener onHeaderClickListener, + WidgetsListDrawableFactory listDrawableFactory, WidgetsListAdapter listAdapter) { mLayoutInflater = layoutInflater; mOnHeaderClickListener = onHeaderClickListener; + mListDrawableFactory = listDrawableFactory; mWidgetsListAdapter = listAdapter; } @@ -45,7 +48,7 @@ public final class WidgetsListSearchHeaderViewHolderBinder implements public WidgetsListSearchHeaderHolder newViewHolder(ViewGroup parent) { WidgetsListHeader header = (WidgetsListHeader) mLayoutInflater.inflate( R.layout.widgets_list_row_header, parent, false); - + header.setBackground(mListDrawableFactory.createHeaderBackgroundDrawable()); return new WidgetsListSearchHeaderHolder(header); } @@ -53,12 +56,13 @@ public final class WidgetsListSearchHeaderViewHolderBinder implements public void bindViewHolder(WidgetsListSearchHeaderHolder viewHolder, WidgetsListSearchHeaderEntry data, int position) { WidgetsListHeader widgetsListHeader = viewHolder.mWidgetsListHeader; - widgetsListHeader.updateListBackground( - /* isFirst= */ position == 0, - /* isLast= */ position == mWidgetsListAdapter.getItemCount() - 1, - /* isExpanded= */ data.isWidgetListShown()); widgetsListHeader.applyFromItemInfoWithIcon(data); widgetsListHeader.setExpanded(data.isWidgetListShown()); + widgetsListHeader.setListDrawableState( + WidgetsListDrawableState.obtain( + /* isFirst= */ position == 0, + /* isLast= */ position == mWidgetsListAdapter.getItemCount() - 1, + /* isExpanded= */ data.isWidgetListShown())); widgetsListHeader.setOnExpandChangeListener(isExpanded -> mOnHeaderClickListener.onHeaderClicked(isExpanded, new PackageUserKey(data.mPkgItem.packageName, data.mPkgItem.user))); diff --git a/src/com/android/launcher3/widget/picker/WidgetsListTableView.java b/src/com/android/launcher3/widget/picker/WidgetsListTableView.java new file mode 100644 index 0000000000..d30e7b68ae --- /dev/null +++ b/src/com/android/launcher3/widget/picker/WidgetsListTableView.java @@ -0,0 +1,59 @@ +/* + * 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.util.AttributeSet; +import android.widget.TableLayout; + +import androidx.annotation.Nullable; +import androidx.annotation.UiThread; + +/** + * Extension of {@link TableLayout} to support the drawable states used by + * {@link WidgetsListDrawableState}. + */ +public class WidgetsListTableView extends TableLayout { + + @Nullable private WidgetsListDrawableState mListDrawableState; + + public WidgetsListTableView(Context context) { + super(context); + } + + public WidgetsListTableView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + /** Sets the {@link WidgetsListDrawableState} and refreshes the background drawable. */ + @UiThread + public void setListDrawableState(WidgetsListDrawableState state) { + if (state == mListDrawableState) return; + mListDrawableState = state; + refreshDrawableState(); + } + + @Override + protected int[] onCreateDrawableState(int extraSpace) { + if (mListDrawableState == null) return super.onCreateDrawableState(extraSpace); + // Augment the state set from the super implementation with the custom states from + // mListDrawableState. + int[] drawableState = + super.onCreateDrawableState(extraSpace + mListDrawableState.mStateSet.length); + mergeDrawableStates(drawableState, mListDrawableState.mStateSet); + return drawableState; + } +} diff --git a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java index 8e310c5d83..7e8c55bfe6 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java @@ -15,8 +15,10 @@ */ package com.android.launcher3.widget.picker; +import static com.android.launcher3.widget.picker.WidgetsListDrawableState.LAST; +import static com.android.launcher3.widget.picker.WidgetsListDrawableState.MIDDLE; + import android.content.Context; -import android.content.res.Resources; import android.util.Log; import android.view.Gravity; import android.view.LayoutInflater; @@ -51,10 +53,8 @@ public final class WidgetsListTableViewHolderBinder private final OnClickListener mIconClickListener; private final OnLongClickListener mIconLongClickListener; private final WidgetPreviewLoader mWidgetPreviewLoader; + private final WidgetsListDrawableFactory mListDrawableFactory; private final WidgetsListAdapter mWidgetsListAdapter; - private final float mTopBottomCornerRadius; - private final float mMiddleCornerRadius; - private final float mJoinedCornerRadius; private boolean mApplyBitmapDeferred = false; public WidgetsListTableViewHolderBinder( @@ -63,19 +63,14 @@ public final class WidgetsListTableViewHolderBinder OnClickListener iconClickListener, OnLongClickListener iconLongClickListener, WidgetPreviewLoader widgetPreviewLoader, + WidgetsListDrawableFactory listDrawableFactory, WidgetsListAdapter listAdapter) { mLayoutInflater = layoutInflater; mIconClickListener = iconClickListener; mIconLongClickListener = iconLongClickListener; mWidgetPreviewLoader = widgetPreviewLoader; + mListDrawableFactory = listDrawableFactory; 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); } /** @@ -97,28 +92,25 @@ public final class WidgetsListTableViewHolderBinder Log.v(TAG, "\nonCreateViewHolder"); } - ViewGroup container = (ViewGroup) mLayoutInflater.inflate( - R.layout.widgets_table_container, parent, false); - return new WidgetsRowViewHolder(container); + WidgetsRowViewHolder viewHolder = + new WidgetsRowViewHolder(mLayoutInflater.inflate( + R.layout.widgets_table_container, parent, false)); + viewHolder.mTableContainer.setBackgroundDrawable( + mListDrawableFactory.createContentBackgroundDrawable()); + return viewHolder; } @Override public void bindViewHolder(WidgetsRowViewHolder holder, WidgetsListContentEntry entry, int position) { - TableLayout table = holder.mTableContainer; + WidgetsListTableView table = holder.mTableContainer; if (DEBUG) { Log.d(TAG, String.format("onBindViewHolder [widget#=%d, table.getChildCount=%d]", entry.mWidgets.size(), table.getChildCount())); } - // 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)); + table.setListDrawableState( + position == mWidgetsListAdapter.getItemCount() - 1 ? LAST : MIDDLE); List> widgetItemsTable = WidgetsTableUtils.groupWidgetItemsIntoTable(entry.mWidgets, mMaxSpansPerRow); diff --git a/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java b/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java index aef1103c2c..618e2cbbd6 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java +++ b/src/com/android/launcher3/widget/picker/WidgetsRowViewHolder.java @@ -15,8 +15,7 @@ */ package com.android.launcher3.widget.picker; -import android.view.ViewGroup; -import android.widget.TableLayout; +import android.view.View; import androidx.recyclerview.widget.RecyclerView.ViewHolder; @@ -25,9 +24,9 @@ import com.android.launcher3.R; /** A {@link ViewHolder} for showing widgets of an app in the full widget picker. */ public final class WidgetsRowViewHolder extends ViewHolder { - public final TableLayout mTableContainer; + public final WidgetsListTableView mTableContainer; - public WidgetsRowViewHolder(ViewGroup v) { + public WidgetsRowViewHolder(View v) { super(v); mTableContainer = v.findViewById(R.id.widgets_table);