Merge "Moving widget background to xml, so that the same constantstate is used for all entries" into tm-qpr-dev am: a75105ef03

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/21381944

Change-Id: Icb8819fae2b4fd21f76faea78e3e341a32a9508f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Sunny Goyal
2023-02-13 18:40:24 +00:00
committed by Automerger Merge Worker
14 changed files with 190 additions and 165 deletions

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--
L -> large radius
s -> small radius
0 -> no radiuls
-->
<!-- MIDDLE : 0 0 s s -->
<item android:state_middle="true">
<shape android:shape="rectangle">
<solid android:color="@color/surface" />
<corners
android:topLeftRadius="0dp"
android:topRightRadius="0dp"
android:bottomLeftRadius="@dimen/widget_list_content_corner_radius"
android:bottomRightRadius="@dimen/widget_list_content_corner_radius" />
</shape>
</item>
<!-- LAST : 0 0 L L -->
<item android:state_last="true">
<shape android:shape="rectangle">
<solid android:color="@color/surface" />
<corners
android:topLeftRadius="0dp"
android:topRightRadius="0dp"
android:bottomLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
android:bottomRightRadius="@dimen/widget_list_top_bottom_corner_radius" />
</shape>
</item>
</selector>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 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.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetTop="@dimen/widget_list_entry_spacing" >
<ripple
android:color="?android:attr/colorControlHighlight"
android:paddingTop="@dimen/widget_list_header_view_vertical_padding"
android:paddingBottom="@dimen/widget_list_header_view_vertical_padding" >
<item android:id="@android:id/mask"
android:drawable="@drawable/bg_widgets_header_states" />
<item android:drawable="@drawable/bg_widgets_header_states" />
</ripple>
</inset>

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--
L -> large radius
s -> small radius
0 -> no radiuls
-->
<!-- SINGLE : L L L L -->
<item android:state_single="true">
<shape android:shape="rectangle">
<solid android:color="@color/surface" />
<corners
android:topLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
android:topRightRadius="@dimen/widget_list_top_bottom_corner_radius"
android:bottomLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
android:bottomRightRadius="@dimen/widget_list_top_bottom_corner_radius" />
</shape>
</item>
<!-- FIRST_EXPANDED : L L 0 0 -->
<item android:state_first="true" android:state_expanded="true">
<shape android:shape="rectangle">
<solid android:color="@color/surface" />
<corners
android:topLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
android:topRightRadius="@dimen/widget_list_top_bottom_corner_radius"
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp" />
</shape>
</item>
<!-- FIRST : L L s s -->
<item android:state_first="true" >
<shape android:shape="rectangle">
<solid android:color="@color/surface" />
<corners
android:topLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
android:topRightRadius="@dimen/widget_list_top_bottom_corner_radius"
android:bottomLeftRadius="@dimen/widget_list_content_corner_radius"
android:bottomRightRadius="@dimen/widget_list_content_corner_radius" />
</shape>
</item>
<!-- MIDDLE_EXPANDED : s s 0 0 -->
<item android:state_middle="true" android:state_expanded="true">
<shape android:shape="rectangle">
<solid android:color="@color/surface" />
<corners
android:topLeftRadius="@dimen/widget_list_content_corner_radius"
android:topRightRadius="@dimen/widget_list_content_corner_radius"
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp" />
</shape>
</item>
<!-- MIDDLE : s s s s -->
<item android:state_middle="true">
<shape android:shape="rectangle">
<solid android:color="@color/surface" />
<corners
android:topLeftRadius="@dimen/widget_list_content_corner_radius"
android:topRightRadius="@dimen/widget_list_content_corner_radius"
android:bottomLeftRadius="@dimen/widget_list_content_corner_radius"
android:bottomRightRadius="@dimen/widget_list_content_corner_radius" />
</shape>
</item>
<!-- LAST : s s L L -->
<item android:state_last="true">
<shape android:shape="rectangle">
<solid android:color="@color/surface" />
<corners
android:topLeftRadius="@dimen/widget_list_content_corner_radius"
android:topRightRadius="@dimen/widget_list_content_corner_radius"
android:bottomLeftRadius="@dimen/widget_list_top_bottom_corner_radius"
android:bottomRightRadius="@dimen/widget_list_top_bottom_corner_radius" />
</shape>
</item>
</selector>

View File

@@ -14,8 +14,8 @@
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
<item android:state_expanded="true"
android:drawable="@drawable/ic_expand_less" />
<item android:state_checked="false"
<item android:state_expanded="false"
android:drawable="@drawable/ic_expand_more" />
</selector>

View File

@@ -23,7 +23,8 @@
android:importantForAccessibility="yes"
android:focusable="true"
launcher:appIconSize="48dp"
android:descendantFocusability="afterDescendants">
android:descendantFocusability="afterDescendants"
android:background="@drawable/bg_widgets_header" >
<ImageView
android:id="@+id/app_icon"
@@ -65,8 +66,11 @@
<!-- This checkbox is not clickable. The outermost LinearLayout is responsible to handle all
click event and update the checkbox state. -->
<CheckBox
<ImageView
android:duplicateParentState="true"
android:id="@+id/toggle"
android:alpha=".6"
android:src="@drawable/widgets_tray_expand_button"
android:layout_marginHorizontal="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -74,7 +78,6 @@
android:layout_alignParentEnd="true"
android:enabled="false"
android:clickable="false"
android:importantForAccessibility="no"
android:button="@drawable/widgets_tray_expand_button"/>
android:importantForAccessibility="no" />
</com.android.launcher3.widget.picker.WidgetsListHeader>

View File

@@ -16,5 +16,6 @@
<com.android.launcher3.widget.picker.WidgetsListTableView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widgets_table"
android:background="@drawable/bg_widgets_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

View File

@@ -274,8 +274,6 @@ public class WidgetsFullSheet extends BaseWidgetSheet
mSuggestedWidgetsHeader = (WidgetsListHeader) layoutInflater.inflate(
R.layout.widgets_list_row_header, mSuggestedWidgetsContainer, false);
mSuggestedWidgetsHeader.setExpanded(true);
mSuggestedWidgetsHeader.setBackground(
new WidgetsListDrawableFactory(getContext()).createHeaderBackgroundDrawable());
PackageItemInfo packageItemInfo = new PackageItemInfo(
/* packageName= */ SUGGESTIONS_PACKAGE_NAME,
@@ -311,9 +309,8 @@ public class WidgetsFullSheet extends BaseWidgetSheet
? mContent.findViewById(R.id.title)
: mSearchScrollView.findViewById(R.id.title);
mRightPane = mIsTwoPane ? mContent.findViewById(R.id.right_pane) : null;
mWidgetsListTableViewHolderBinder = new WidgetsListTableViewHolderBinder(
layoutInflater, this, this,
new WidgetsListDrawableFactory(getContext()));
mWidgetsListTableViewHolderBinder =
new WidgetsListTableViewHolderBinder(layoutInflater, this, this);
onRecommendedWidgetsBound();
onWidgetsBound();

View File

@@ -108,19 +108,15 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
mHeaderChangeListener = headerChangeListener;
mContext = context;
mDiffReporter = new WidgetsDiffReporter(iconCache, this);
WidgetsListDrawableFactory listDrawableFactory = new WidgetsListDrawableFactory(context);
mViewHolderBinders.put(
VIEW_TYPE_WIDGETS_LIST,
new WidgetsListTableViewHolderBinder(
layoutInflater, iconClickListener, iconLongClickListener,
listDrawableFactory));
layoutInflater, iconClickListener, iconLongClickListener));
mViewHolderBinders.put(
VIEW_TYPE_WIDGETS_HEADER,
new WidgetsListHeaderViewHolderBinder(
layoutInflater,
/* onHeaderClickListener= */ this,
listDrawableFactory));
layoutInflater, /* onHeaderClickListener= */ this));
mViewHolderBinders.put(
VIEW_TYPE_WIDGETS_SPACE,
new WidgetsSpaceViewHolderBinder(emptySpaceHeightProvider));

View File

@@ -1,122 +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 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.InsetDrawable;
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;
private final int mVerticalPadding;
private final int mHeaderMargin;
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));
mVerticalPadding =
res.getDimensionPixelSize(R.dimen.widget_list_header_view_vertical_padding);
mHeaderMargin = res.getDimensionPixelSize(R.dimen.widget_list_entry_spacing);
}
/**
* 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));
RippleDrawable ripple =
new RippleDrawable(mRippleColor, /* content= */ stateList, /* mask= */ stateList);
ripple.setPadding(0, mVerticalPadding, 0, mVerticalPadding);
return new InsetDrawable(ripple, 0, mHeaderMargin, 0, 0);
}
/**
* 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;
}
}

View File

@@ -28,7 +28,6 @@ import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -67,7 +66,6 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd
private TextView mTitle;
private TextView mSubtitle;
private GradientDrawable mBackground;
private CheckBox mExpandToggle;
private boolean mEnableIconUpdateAnimation = false;
private boolean mIsExpanded = false;
@@ -101,9 +99,8 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd
mAppIcon = findViewById(R.id.app_icon);
mTitle = findViewById(R.id.app_title);
mSubtitle = findViewById(R.id.app_subtitle);
mExpandToggle = findViewById(R.id.toggle);
if (mIsTwoPane) {
mExpandToggle.setVisibility(GONE);
findViewById(R.id.toggle).setVisibility(GONE);
}
setAccessibilityDelegate(new AccessibilityDelegate() {
@@ -153,7 +150,6 @@ public final class WidgetsListHeader extends LinearLayout implements ItemInfoUpd
@UiThread
public void setExpanded(boolean isExpanded) {
this.mIsExpanded = isExpanded;
mExpandToggle.setChecked(isExpanded);
if (mIsTwoPane) {
if (Utilities.isDarkTheme(getContext())) {
if (mIsExpanded) {

View File

@@ -32,22 +32,17 @@ public final class WidgetsListHeaderViewHolderBinder implements
ViewHolderBinder<WidgetsListHeaderEntry, WidgetsListHeaderHolder> {
private final LayoutInflater mLayoutInflater;
private final OnHeaderClickListener mOnHeaderClickListener;
private final WidgetsListDrawableFactory mListDrawableFactory;
public WidgetsListHeaderViewHolderBinder(LayoutInflater layoutInflater,
OnHeaderClickListener onHeaderClickListener,
WidgetsListDrawableFactory listDrawableFactory) {
OnHeaderClickListener onHeaderClickListener) {
mLayoutInflater = layoutInflater;
mOnHeaderClickListener = onHeaderClickListener;
mListDrawableFactory = listDrawableFactory;
}
@Override
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);
return new WidgetsListHeaderHolder((WidgetsListHeader) mLayoutInflater.inflate(
R.layout.widgets_list_row_header, parent, false));
}
@Override

View File

@@ -51,17 +51,14 @@ public final class WidgetsListTableViewHolderBinder
private final LayoutInflater mLayoutInflater;
private final OnClickListener mIconClickListener;
private final OnLongClickListener mIconLongClickListener;
private final WidgetsListDrawableFactory mListDrawableFactory;
public WidgetsListTableViewHolderBinder(
LayoutInflater layoutInflater,
OnClickListener iconClickListener,
OnLongClickListener iconLongClickListener,
WidgetsListDrawableFactory listDrawableFactory) {
OnLongClickListener iconLongClickListener) {
mLayoutInflater = layoutInflater;
mIconClickListener = iconClickListener;
mIconLongClickListener = iconLongClickListener;
mListDrawableFactory = listDrawableFactory;
}
@Override
@@ -70,12 +67,8 @@ public final class WidgetsListTableViewHolderBinder
Log.v(TAG, "\nonCreateViewHolder");
}
WidgetsRowViewHolder viewHolder =
new WidgetsRowViewHolder(mLayoutInflater.inflate(
return new WidgetsRowViewHolder(mLayoutInflater.inflate(
R.layout.widgets_table_container, parent, false));
viewHolder.tableContainer.setBackgroundDrawable(
mListDrawableFactory.createContentBackgroundDrawable());
return viewHolder;
}
@Override

View File

@@ -90,8 +90,7 @@ public final class WidgetsListHeaderViewHolderBinderTest {
}).when(mIconCache).getTitleNoCache(any());
mViewHolderBinder = new WidgetsListHeaderViewHolderBinder(
LayoutInflater.from(mContext),
mOnHeaderClickListener,
new WidgetsListDrawableFactory(mContext));
mOnHeaderClickListener);
}
@Test

View File

@@ -96,8 +96,7 @@ public final class WidgetsListTableViewHolderBinderTest {
mViewHolderBinder = new WidgetsListTableViewHolderBinder(
LayoutInflater.from(mContext),
mOnIconClickListener,
mOnLongClickListener,
new WidgetsListDrawableFactory(mContext));
mOnLongClickListener);
}
@Test