From 11773f47d2d0ce7a082d4ea69087c36898a10ad5 Mon Sep 17 00:00:00 2001 From: Steven Ng Date: Thu, 25 Feb 2021 22:54:37 +0000 Subject: [PATCH] Show widget previews in their expected cell sizes 1. Show widget previews in their expected cell sizes. 2. Update the bottom picker to use a table layout rather than a horizontal scrollbar. 3. Move the title and cell size description to the bottom of the preview. Test: Run AddConfigWidgetTest Manually open full and bottom widgets picker and observe widget previews. Video: https://drive.google.com/file/d/1K8A8hK5B4FgPTsX3cb-Yt4a_VjI0pk-w/view?usp=sharing Bug: 179797520 Change-Id: I938612cb2e2477ce4a3a2d6c8891a0a36fc0978c --- res/layout/live_preview_widget_cell.xml | 6 +- res/layout/widget_cell.xml | 4 +- res/layout/widget_cell_content.xml | 66 +++++++-------- res/layout/widgets_bottom_sheet.xml | 17 ++-- res/layout/widgets_table_container.xml | 1 + res/values/dimens.xml | 4 +- .../android/launcher3/widget/WidgetCell.java | 28 +++++-- .../launcher3/widget/WidgetsBottomSheet.java | 84 +++++++++++-------- .../widget/picker/WidgetsFullSheet.java | 5 +- .../WidgetsListTableViewHolderBinder.java | 2 + 10 files changed, 123 insertions(+), 94 deletions(-) diff --git a/res/layout/live_preview_widget_cell.xml b/res/layout/live_preview_widget_cell.xml index 7a42d195f0..1e1ce6e42e 100644 --- a/res/layout/live_preview_widget_cell.xml +++ b/res/layout/live_preview_widget_cell.xml @@ -15,14 +15,16 @@ --> - + \ No newline at end of file diff --git a/res/layout/widget_cell.xml b/res/layout/widget_cell.xml index 148a99b1ef..73a573754a 100644 --- a/res/layout/widget_cell.xml +++ b/res/layout/widget_cell.xml @@ -15,8 +15,10 @@ --> - - - - - - - - - + android:layout_weight="1" + android:layout_marginVertical="8dp" /> + + + + + + + \ No newline at end of file diff --git a/res/layout/widgets_bottom_sheet.xml b/res/layout/widgets_bottom_sheet.xml index 3fdfc96667..c1b2cbff12 100644 --- a/res/layout/widgets_bottom_sheet.xml +++ b/res/layout/widgets_bottom_sheet.xml @@ -44,11 +44,16 @@ android:textSize="14sp" android:text="@string/long_press_widget_to_add"/> - + + + \ No newline at end of file diff --git a/res/layout/widgets_table_container.xml b/res/layout/widgets_table_container.xml index ffa239a699..c4dfe7e7c3 100644 --- a/res/layout/widgets_table_container.xml +++ b/res/layout/widgets_table_container.xml @@ -18,4 +18,5 @@ android:id="@+id/widgets_table" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginHorizontal="8dp" android:background="?android:attr/colorPrimaryDark" /> diff --git a/res/values/dimens.xml b/res/values/dimens.xml index acc6466caa..ee917996e5 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -102,8 +102,8 @@ 16sp - 8dp - 16dp + 8dp + 16dp 0.5dp 1dp diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java index bef91d2af4..c6593f869e 100644 --- a/src/com/android/launcher3/widget/WidgetCell.java +++ b/src/com/android/launcher3/widget/WidgetCell.java @@ -24,7 +24,6 @@ import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnLayoutChangeListener; -import android.view.ViewGroup; import android.view.ViewPropertyAnimator; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.LinearLayout; @@ -60,6 +59,8 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { /** Widget preview width is calculated by multiplying this factor to the widget cell width. */ private static final float PREVIEW_SCALE = 0.8f; + private int mPreviewWidth; + private int mPreviewHeight; protected int mPresetPreviewSize; private int mCellSize; @@ -106,6 +107,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { private void setContainerWidth() { mCellSize = (int) (mDeviceProfile.allAppsIconSizePx * WIDTH_SCALE); mPresetPreviewSize = (int) (mCellSize * PREVIEW_SCALE); + mPreviewWidth = mPreviewHeight = mPresetPreviewSize; } @Override @@ -128,6 +130,7 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { mWidgetImage.setBitmap(null, null); mWidgetName.setText(null); mWidgetDims.setText(null); + mPreviewWidth = mPreviewHeight = mPresetPreviewSize; if (mActiveRequest != null) { mActiveRequest.cancel(); @@ -181,6 +184,11 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { return; } if (bitmap != null) { + LayoutParams layoutParams = (LayoutParams) mWidgetImage.getLayoutParams(); + layoutParams.width = bitmap.getWidth(); + layoutParams.height = bitmap.getHeight(); + mWidgetImage.setLayoutParams(layoutParams); + mWidgetImage.setBitmap(bitmap, mWidgetPreviewLoader.getBadgeForUser(mItem.user, BaseIconFactory.getBadgeSizeForIconSize(mDeviceProfile.allAppsIconSizePx))); if (mAnimatePreview) { @@ -197,8 +205,16 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { if (mActiveRequest != null) { return; } - mActiveRequest = mWidgetPreviewLoader.getPreview( - mItem, mPresetPreviewSize, mPresetPreviewSize, this); + mActiveRequest = mWidgetPreviewLoader.getPreview(mItem, mPreviewWidth, mPreviewHeight, + this); + } + + /** Sets the widget preview image size in number of cells. */ + public void setPreviewSize(int spanX, int spanY) { + int padding = 2 * getResources() + .getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding); + mPreviewWidth = mDeviceProfile.cellWidthPx * spanX + padding; + mPreviewHeight = mDeviceProfile.cellHeightPx * spanY + padding; } @Override @@ -232,12 +248,6 @@ public class WidgetCell extends LinearLayout implements OnLayoutChangeListener { return ""; } - @Override - public void setLayoutParams(ViewGroup.LayoutParams params) { - params.width = params.height = mCellSize; - super.setLayoutParams(params); - } - @Override public CharSequence getAccessibilityClassName() { return WidgetCell.class.getName(); diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java index 223cda272a..6abbf21019 100644 --- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java +++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java @@ -24,22 +24,25 @@ import android.graphics.Rect; import android.util.AttributeSet; import android.util.IntProperty; import android.util.Pair; -import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.animation.Interpolator; +import android.widget.ScrollView; +import android.widget.TableLayout; +import android.widget.TableRow; import android.widget.TextView; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; -import com.android.launcher3.ResourceUtils; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.dragndrop.LivePreviewWidgetCell; import com.android.launcher3.model.WidgetItem; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.PackageUserKey; +import com.android.launcher3.widget.util.WidgetsTableUtils; import java.util.List; @@ -65,6 +68,8 @@ public class WidgetsBottomSheet extends BaseWidgetSheet implements Insettable { private static final int DEFAULT_CLOSE_DURATION = 200; private ItemInfo mOriginalItemInfo; private Rect mInsets; + private final int mMaxTableHeight; + private int mMaxHorizontalSpan = 4; public WidgetsBottomSheet(Context context, AttributeSet attrs) { this(context, attrs, 0); @@ -75,12 +80,41 @@ public class WidgetsBottomSheet extends BaseWidgetSheet implements Insettable { setWillNotDraw(false); mInsets = new Rect(); mContent = this; + DeviceProfile deviceProfile = mLauncher.getDeviceProfile(); + // Set the max table height to 2 / 3 of the grid height so that the bottom picker won't + // take over the entire view vertically. + mMaxTableHeight = deviceProfile.inv.numRows * 2 / 3 * deviceProfile.cellHeightPx; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + int paddingPx = 2 * getResources().getDimensionPixelOffset( + R.dimen.widget_cell_horizontal_padding); + int maxHorizontalSpan = findViewById(R.id.widgets_table).getMeasuredWidth() + / (mLauncher.getDeviceProfile().cellWidthPx + paddingPx); + + if (mMaxHorizontalSpan != maxHorizontalSpan) { + // Ensure the table layout is showing widgets in the right column after measure. + mMaxHorizontalSpan = maxHorizontalSpan; + onWidgetsBound(); + } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); setTranslationShift(mTranslationShift); + + // Ensure the scroll view height is not larger than mMaxTableHeight, which is a value + // smaller than the entire screen height. + ScrollView widgetsTableScrollView = findViewById(R.id.widgets_table_scroll_view); + if (widgetsTableScrollView.getMeasuredHeight() > mMaxTableHeight) { + ViewGroup.LayoutParams layoutParams = widgetsTableScrollView.getLayoutParams(); + layoutParams.height = mMaxTableHeight; + widgetsTableScrollView.setLayoutParams(layoutParams); + } } public void populateAndShow(ItemInfo itemInfo) { @@ -101,39 +135,21 @@ public class WidgetsBottomSheet extends BaseWidgetSheet implements Insettable { mOriginalItemInfo.getTargetComponent().getPackageName(), mOriginalItemInfo.user)); - ViewGroup widgetRow = findViewById(R.id.widgets); - ViewGroup widgetCells = widgetRow.findViewById(R.id.widgets_cell_list); + TableLayout widgetsTable = findViewById(R.id.widgets_table); + widgetsTable.removeAllViews(); - widgetCells.removeAllViews(); - - for (int i = 0; i < widgets.size(); i++) { - WidgetCell widget = addItemCell(widgetCells); - widget.applyFromCellItem(widgets.get(i), LauncherAppState.getInstance(mLauncher) - .getWidgetCache()); - widget.ensurePreview(); - widget.setVisibility(View.VISIBLE); - if (i < widgets.size() - 1) { - addDivider(widgetCells); - } - } - - if (widgets.size() == 1) { - // If there is only one widget, we want to center it instead of left-align. - WidgetsBottomSheet.LayoutParams params = (WidgetsBottomSheet.LayoutParams) - widgetRow.getLayoutParams(); - params.gravity = Gravity.CENTER_HORIZONTAL; - } else { - // Otherwise, add an empty view to the start as padding (but still scroll edge to edge). - View leftPaddingView = LayoutInflater.from(getContext()).inflate( - R.layout.widget_list_divider, widgetRow, false); - leftPaddingView.getLayoutParams().width = ResourceUtils.pxFromDp( - 16, getResources().getDisplayMetrics()); - widgetCells.addView(leftPaddingView, 0); - } - } - - private void addDivider(ViewGroup parent) { - LayoutInflater.from(getContext()).inflate(R.layout.widget_list_divider, parent, true); + WidgetsTableUtils.groupWidgetItemsIntoTable(widgets, mMaxHorizontalSpan).forEach(row -> { + TableRow tableRow = new TableRow(getContext()); + row.forEach(widgetItem -> { + WidgetCell widget = addItemCell(tableRow); + widget.setPreviewSize(widgetItem.spanX, widgetItem.spanY); + widget.applyFromCellItem(widgetItem, LauncherAppState.getInstance(mLauncher) + .getWidgetCache()); + widget.ensurePreview(); + widget.setVisibility(View.VISIBLE); + }); + widgetsTable.addView(tableRow); + }); } protected WidgetCell addItemCell(ViewGroup parent) { diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java index 39953b17e2..fddb93112c 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java +++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java @@ -198,8 +198,9 @@ public class WidgetsFullSheet extends BaseWidgetSheet setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec)); - int maxSpansPerRow = getMeasuredWidth() / (deviceProfile.cellWidthPx - + deviceProfile.workspaceCellPaddingXPx); + int paddingPx = 2 * getResources().getDimensionPixelOffset( + R.dimen.widget_cell_horizontal_padding); + int maxSpansPerRow = getMeasuredWidth() / (deviceProfile.cellWidthPx + paddingPx); mAdapters.get(AdapterHolder.PRIMARY).mWidgetsListAdapter.setMaxHorizontalSpansPerRow( maxSpansPerRow); if (mHasWorkProfile) { diff --git a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java index 2355700e72..9c8684a0bc 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java @@ -112,7 +112,9 @@ public final class WidgetsListTableViewHolderBinder TableRow row = (TableRow) table.getChildAt(i); row.setVisibility(View.VISIBLE); WidgetCell widget = (WidgetCell) row.getChildAt(j); + widget.clear(); WidgetItem widgetItem = widgetItemsPerRow.get(j); + widget.setPreviewSize(widgetItem.spanX, widgetItem.spanY); widget.applyFromCellItem(widgetItem, mWidgetPreviewLoader); widget.setApplyBitmapDeferred(mApplyBitmapDeferred); widget.ensurePreview();