Use bouncy grid option item
Use the grid option item bouncy selected animation background.
Test: Manully tested.
Bug: 362237825
Flag: com.android.systemui.shared.new_customization_picker_ui
Change-Id: Ia311cfe6a6be39a42f752ca4f0015d690b33dac6
diff --git a/res/layout/grid_option2.xml b/res/layout/grid_option2.xml
new file mode 100644
index 0000000..437b95b
--- /dev/null
+++ b/res/layout/grid_option2.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2024 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.
+ ~
+ -->
+
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="@dimen/option_item_size"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center_horizontal"
+ android:clipChildren="false">
+
+ <FrameLayout
+ android:layout_width="@dimen/option_item_size"
+ android:layout_height="@dimen/option_item_size"
+ android:clipChildren="false">
+
+ <com.android.wallpaper.picker.option.ui.view.OptionItemBackground
+ android:id="@id/background"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/option_item_background"
+ android:importantForAccessibility="no" />
+
+ <ImageView
+ android:id="@id/foreground"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_gravity="center" />
+
+ </FrameLayout>
+
+ <View
+ android:layout_width="0dp"
+ android:layout_height="8dp" />
+
+ <TextView
+ android:id="@id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@color/system_on_surface"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:textSize="12sp"
+ android:text="Placeholder for stable size calculation, please do not remove."
+ tools:ignore="HardcodedText" />
+
+</LinearLayout>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 0c36753..4f1062f 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -189,6 +189,7 @@
<dimen name="floating_sheet_tab_clock_font_toolbar_top_margin">16dp</dimen>
<dimen name="floating_sheet_tab_clock_font_toolbar_bottom_margin">8dp</dimen>
<dimen name="floating_sheet_list_item_horizontal_space">4dp</dimen>
+ <dimen name="floating_sheet_grid_list_item_horizontal_space">10dp</dimen>
<dimen name="floating_sheet_list_item_vertical_space">4dp</dimen>
<dimen name="floating_sheet_clock_style_option_list_margin_bottom">8dp</dimen>
<dimen name="floating_sheet_clock_style_option_width">80dp</dimen>
diff --git a/src/com/android/wallpaper/customization/ui/binder/ShapeGridFloatingSheetBinder.kt b/src/com/android/wallpaper/customization/ui/binder/ShapeGridFloatingSheetBinder.kt
index 5f292bd..138a253 100644
--- a/src/com/android/wallpaper/customization/ui/binder/ShapeGridFloatingSheetBinder.kt
+++ b/src/com/android/wallpaper/customization/ui/binder/ShapeGridFloatingSheetBinder.kt
@@ -43,6 +43,7 @@
import com.android.wallpaper.picker.customization.ui.view.adapter.FloatingToolbarTabAdapter
import com.android.wallpaper.picker.customization.ui.viewmodel.ColorUpdateViewModel
import com.android.wallpaper.picker.option.ui.adapter.OptionItemAdapter
+import com.android.wallpaper.picker.option.ui.adapter.OptionItemAdapter2
import com.android.wallpaper.picker.option.ui.binder.OptionItemBinder
import java.lang.ref.WeakReference
import kotlinx.coroutines.CoroutineDispatcher
@@ -97,7 +98,7 @@
val gridContent = view.requireViewById<View>(R.id.app_grid_container)
val gridOptionListAdapter =
- createGridOptionItemAdapter(view.context, lifecycleOwner, backgroundDispatcher)
+ createGridOptionItemAdapter(lifecycleOwner, backgroundDispatcher)
val gridOptionList =
view.requireViewById<RecyclerView>(R.id.grid_options).also {
it.initGridOptionList(view.context, gridOptionListAdapter)
@@ -243,8 +244,7 @@
),
itemHorizontalSpacePx =
context.resources.getDimensionPixelSize(
- com.android.themepicker.R.dimen
- .floating_sheet_list_item_horizontal_space
+ R.dimen.floating_sheet_list_item_horizontal_space
),
)
)
@@ -253,30 +253,23 @@
}
private fun createGridOptionItemAdapter(
- context: Context,
lifecycleOwner: LifecycleOwner,
backgroundDispatcher: CoroutineDispatcher,
- ): OptionItemAdapter<GridIconViewModel> =
- OptionItemAdapter(
- layoutResourceId = R.layout.grid_option,
+ ): OptionItemAdapter2<GridIconViewModel> =
+ OptionItemAdapter2(
+ layoutResourceId = R.layout.grid_option2,
lifecycleOwner = lifecycleOwner,
backgroundDispatcher = backgroundDispatcher,
- foregroundTintSpec =
- OptionItemBinder.TintSpec(
- selectedColor =
- context.getColor(com.android.wallpaper.R.color.system_on_surface),
- unselectedColor =
- context.getColor(com.android.wallpaper.R.color.system_on_surface),
- ),
- bindIcon = { foregroundView: View, gridIcon: GridIconViewModel ->
- val imageView = foregroundView as? ImageView
+ bindPayload = { view: View, gridIcon: GridIconViewModel ->
+ val imageView = view.findViewById(R.id.foreground) as? ImageView
imageView?.let { GridIconViewBinder.bind(imageView, gridIcon) }
+ return@OptionItemAdapter2 null
},
)
private fun RecyclerView.initGridOptionList(
context: Context,
- adapter: OptionItemAdapter<GridIconViewModel>,
+ adapter: OptionItemAdapter2<GridIconViewModel>,
) {
apply {
this.layoutManager = LinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
@@ -288,8 +281,7 @@
),
itemHorizontalSpacePx =
context.resources.getDimensionPixelSize(
- com.android.themepicker.R.dimen
- .floating_sheet_list_item_horizontal_space
+ R.dimen.floating_sheet_grid_list_item_horizontal_space
),
)
)
diff --git a/src/com/android/wallpaper/customization/ui/viewmodel/ShapeGridPickerViewModel.kt b/src/com/android/wallpaper/customization/ui/viewmodel/ShapeGridPickerViewModel.kt
index 7f3c4cb..1e19e80 100644
--- a/src/com/android/wallpaper/customization/ui/viewmodel/ShapeGridPickerViewModel.kt
+++ b/src/com/android/wallpaper/customization/ui/viewmodel/ShapeGridPickerViewModel.kt
@@ -29,6 +29,7 @@
import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
import com.android.wallpaper.picker.customization.ui.viewmodel.FloatingToolbarTabViewModel
import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel2
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -126,7 +127,7 @@
overridingGridOptionKey ?: selectedGridOption.key.value
}
- val gridOptions: Flow<List<OptionItemViewModel<GridIconViewModel>>> =
+ val gridOptions: Flow<List<OptionItemViewModel2<GridIconViewModel>>> =
interactor.gridOptions
.filterNotNull()
.map { gridOptions -> gridOptions.map { toGridOptionItemViewModel(it) } }
@@ -184,7 +185,7 @@
private fun toGridOptionItemViewModel(
option: GridOptionModel
- ): OptionItemViewModel<GridIconViewModel> {
+ ): OptionItemViewModel2<GridIconViewModel> {
val iconShapePath =
context.resources.getString(
Resources.getSystem()
@@ -203,7 +204,7 @@
initialValue = false,
)
- return OptionItemViewModel(
+ return OptionItemViewModel2(
key = MutableStateFlow(option.key),
payload =
GridIconViewModel(columns = option.cols, rows = option.rows, path = iconShapePath),
diff --git a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ShapeGridPickerViewModelTest.kt b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ShapeGridPickerViewModelTest.kt
index c99acca..71ea0d9 100644
--- a/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ShapeGridPickerViewModelTest.kt
+++ b/tests/robotests/src/com/android/wallpaper/customization/ui/viewmodel/ShapeGridPickerViewModelTest.kt
@@ -27,6 +27,7 @@
import com.android.customization.picker.grid.ui.viewmodel.ShapeIconViewModel
import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel2
import com.android.wallpaper.testing.collectLastValue
import com.google.common.truth.Truth.assertThat
import dagger.hilt.android.qualifiers.ApplicationContext
@@ -159,7 +160,7 @@
testScope.runTest {
val selectedGridOption = collectLastValue(underTest.selectedGridOption)
- assertOptionItem(
+ assertGridItem(
optionItem = selectedGridOption(),
key = "normal",
payload = GridIconViewModel(5, 5, iconShapePath),
@@ -183,7 +184,7 @@
onPracticalOptionClick()?.invoke()
onApply()?.invoke()
- assertOptionItem(
+ assertGridItem(
optionItem = selectedGridOption(),
key = "practical",
payload = GridIconViewModel(4, 5, iconShapePath),
@@ -199,7 +200,7 @@
testScope.runTest {
val optionItems = collectLastValue(underTest.gridOptions)
- assertOptionItem(
+ assertGridItem(
optionItem = optionItems()?.get(0),
key = "normal",
payload = GridIconViewModel(5, 5, iconShapePath),
@@ -208,7 +209,7 @@
isSelected = true,
isEnabled = true,
)
- assertOptionItem(
+ assertGridItem(
optionItem = optionItems()?.get(1),
key = "practical",
payload = GridIconViewModel(4, 5, iconShapePath),
@@ -229,7 +230,7 @@
onPracticalOptionClick()?.invoke()
- assertOptionItem(
+ assertGridItem(
optionItem = optionItems()?.get(0),
key = "normal",
payload = GridIconViewModel(5, 5, iconShapePath),
@@ -238,7 +239,7 @@
isSelected = false,
isEnabled = true,
)
- assertOptionItem(
+ assertGridItem(
optionItem = optionItems()?.get(1),
key = "practical",
payload = GridIconViewModel(4, 5, iconShapePath),
@@ -267,8 +268,8 @@
assertThat(optionItem.isEnabled).isEqualTo(isEnabled)
}
- private fun TestScope.assertOptionItem(
- optionItem: OptionItemViewModel<GridIconViewModel>?,
+ private fun TestScope.assertGridItem(
+ optionItem: OptionItemViewModel2<GridIconViewModel>?,
key: String,
payload: GridIconViewModel?,
text: Text,