diff options
author | Alejandro Nijamkin <nijamkin@google.com> | 2022-12-22 16:36:47 -0800 |
---|---|---|
committer | Alejandro Nijamkin <nijamkin@google.com> | 2022-12-27 12:27:17 -0800 |
commit | a547706feed5bac41bea889ba6b4252e9b46b3db (patch) | |
tree | 598f0fc172fbcf79c10cc14de2c2346b427507ce | |
parent | 2fe5f2def3238b9519bc9d98aa29cea2a65f17ee (diff) |
Beautifies picker disabled dialogs (2/2).
Makes the dialog look like its spec.
Fix: 262773261
Test: https://screenshot.googleplex.com/6vukXFZHgDdQW7X
Change-Id: Ic4acf5bf8d7a28cfd4c2cec9b82ee1c85550c056
7 files changed, 172 insertions, 48 deletions
diff --git a/res/drawable/button_background.xml b/res/drawable/button_background.xml new file mode 100644 index 00000000..24c7253c --- /dev/null +++ b/res/drawable/button_background.xml @@ -0,0 +1,20 @@ +<!-- + 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. +--> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <corners android:radius="50dp" /> + <solid android:color="@color/color_accent_primary" /> +</shape> diff --git a/res/layout/keyguard_quick_affordance_enablement_dialog.xml b/res/layout/keyguard_quick_affordance_enablement_dialog.xml new file mode 100644 index 00000000..d6ba1054 --- /dev/null +++ b/res/layout/keyguard_quick_affordance_enablement_dialog.xml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Copyright (C) 2022 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" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:background="@drawable/keyguard_quick_affordance_picker_background" + android:orientation="vertical" + android:padding="24dp"> + + <ImageView + android:id="@+id/icon" + android:layout_width="32dp" + android:layout_height="32dp" + android:tint="@color/color_accent_primary" + android:layout_gravity="center_horizontal" + android:layout_marginBottom="16dp" /> + + <TextView + android:id="@+id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center" + android:textAppearance="@style/TextAppearance.MaterialComponents.Headline4" + android:layout_gravity="center_horizontal" + android:layout_marginBottom="16dp" /> + + <TextView + android:id="@+id/message" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.MaterialComponents.Body1" + android:layout_gravity="center_horizontal" + android:layout_marginBottom="38dp" /> + + <Button + android:id="@+id/button" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + style="@style/ActionPrimaryButton" + android:background="@drawable/button_background" + android:layout_gravity="end" /> + +</LinearLayout> diff --git a/res/values/strings.xml b/res/values/strings.xml index 63fb5602..13fc8a01 100755 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -294,7 +294,7 @@ enabled. The dialog contains a list of instructions that the user needs to take in order to enable the option before it can be selected again. [CHAR LIMIT=NONE]. --> - <string name="keyguard_affordance_enablement_dialog_title">Additional setup needed</string> + <string name="keyguard_affordance_enablement_dialog_title">To select `<xliff:g id="appName" example="Wallet">%1$s</xliff:g>` check the following</string> <!-- Template for an action that opens a specific app. [CHAR LIMIT=16] diff --git a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceEnablementDialogBinder.kt b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceEnablementDialogBinder.kt new file mode 100644 index 00000000..809e09d6 --- /dev/null +++ b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceEnablementDialogBinder.kt @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2022 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.customization.picker.quickaffordance.ui.binder + +import android.view.View +import android.widget.ImageView +import android.widget.TextView +import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel +import com.android.wallpaper.R + +object KeyguardQuickAffordanceEnablementDialogBinder { + + fun bind( + view: View, + viewModel: KeyguardQuickAffordancePickerViewModel.DialogViewModel, + onDismissed: () -> Unit, + ) { + view.requireViewById<ImageView>(R.id.icon).setImageDrawable(viewModel.icon) + view.requireViewById<TextView>(R.id.title).text = + view.context.getString( + R.string.keyguard_affordance_enablement_dialog_title, + viewModel.name + ) + view.requireViewById<TextView>(R.id.message).text = buildString { + viewModel.instructions.forEachIndexed { index, instruction -> + append(instruction) + if (index < viewModel.instructions.size - 1) { + append("\n") + } + } + } + view.requireViewById<TextView>(R.id.button).apply { + text = viewModel.actionText + setOnClickListener { + if (viewModel.intent != null) { + view.context.startActivity(viewModel.intent) + } else { + onDismissed() + } + } + } + } +} diff --git a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePickerBinder.kt b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePickerBinder.kt index 62f2e268..389f8f62 100644 --- a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePickerBinder.kt +++ b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePickerBinder.kt @@ -20,8 +20,8 @@ package com.android.customization.picker.quickaffordance.ui.binder import android.app.AlertDialog import android.app.Dialog import android.content.Context -import android.content.DialogInterface import android.graphics.Rect +import android.view.LayoutInflater import android.view.View import androidx.core.view.ViewCompat import androidx.lifecycle.Lifecycle @@ -88,7 +88,6 @@ object KeyguardQuickAffordancePickerBinder { onDismissed = viewModel::onDialogDismissed ) } else { - dialog?.dismiss() null } } @@ -102,34 +101,21 @@ object KeyguardQuickAffordancePickerBinder { request: KeyguardQuickAffordancePickerViewModel.DialogViewModel, onDismissed: () -> Unit, ): Dialog { - // TODO(b/254858701): make this dialog prettier and probably use a DialogFragment. - return AlertDialog.Builder(context, context.themeResId) - .setTitle(context.getString(R.string.keyguard_affordance_enablement_dialog_title)) - .setMessage( - buildString { - append(request.instructionHeader) - if (request.instructions.isNotEmpty()) { - append("\n") - } - request.instructions.forEachIndexed { index, instruction -> - append(instruction) - if (index < request.instructions.size - 1) { - append("\n") - } - } - } - ) - .setOnDismissListener { onDismissed.invoke() } - .setPositiveButton( - request.actionText, - if (request.intent != null) { - DialogInterface.OnClickListener { _, _ -> - context.startActivity(request.intent) - } - } else { - DialogInterface.OnClickListener { _, _ -> onDismissed() } - }, - ) + val view: View = + LayoutInflater.from(context) + .inflate( + R.layout.keyguard_quick_affordance_enablement_dialog, + null, + ) + KeyguardQuickAffordanceEnablementDialogBinder.bind( + view = view, + viewModel = request, + onDismissed = onDismissed, + ) + + return AlertDialog.Builder(context, R.style.LightDialogTheme) + .setView(view) + .setOnDismissListener { onDismissed() } .show() } diff --git a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt index f87c0990..e0e5ca8a 100644 --- a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt +++ b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt @@ -167,8 +167,9 @@ private constructor( ) + affordances.map { affordance -> val isSelected = selectedAffordanceIds.contains(affordance.id) + val affordanceIcon = getAffordanceIcon(affordance.iconResourceId) KeyguardQuickAffordanceViewModel( - icon = getAffordanceIcon(affordance.iconResourceId), + icon = affordanceIcon, contentDescription = affordance.name, isSelected = isSelected, onClicked = @@ -191,13 +192,9 @@ private constructor( } else { { showEnablementDialog( - instructionHeader = - affordance.enablementInstructions.first(), - instructions = - affordance.enablementInstructions.subList( - 1, - affordance.enablementInstructions.size - ), + icon = affordanceIcon, + name = affordance.name, + instructions = affordance.enablementInstructions, actionText = affordance.enablementActionText, actionComponentName = affordance.enablementActionComponentName, @@ -249,14 +246,16 @@ private constructor( } private fun showEnablementDialog( - instructionHeader: String, + icon: Drawable, + name: String, instructions: List<String>, actionText: String?, actionComponentName: String?, ) { _dialog.value = DialogViewModel( - instructionHeader = instructionHeader, + icon = icon, + name = name, instructions = instructions, actionText = actionText ?: applicationContext.getString( @@ -317,8 +316,11 @@ private constructor( /** Encapsulates a request to show a dialog. */ data class DialogViewModel( - /** The header for the instructions section. */ - val instructionHeader: String, + /** An icon to show. */ + val icon: Drawable, + + /** Name of the affordance. */ + val name: String, /** The set of instructions to show below the header. */ val instructions: List<String>, diff --git a/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt b/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt index 9c3e87cc..6706f173 100644 --- a/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt +++ b/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt @@ -233,7 +233,7 @@ class KeyguardQuickAffordancePickerViewModelTest { val quickAffordances = collectLastValue(underTest.quickAffordances) val dialog = collectLastValue(underTest.dialog) - val enablementInstructions = listOf("header", "enablementInstructions") + val enablementInstructions = listOf("instruction1", "instruction2") val enablementActionText = "enablementActionText" val packageName = "packageName" val action = "action" @@ -244,7 +244,7 @@ class KeyguardQuickAffordancePickerViewModelTest { KeyguardQuickAffordanceProviderClient.Affordance( id = "disabled", name = "disabled", - iconResourceId = 0, + iconResourceId = 1, isEnabled = false, enablementInstructions = enablementInstructions, enablementActionText = enablementActionText, @@ -256,9 +256,8 @@ class KeyguardQuickAffordancePickerViewModelTest { quickAffordances()?.get(affordanceIndex + 1)?.onClicked?.invoke() // We expect there to be a dialog that should be shown: - assertThat(dialog()?.instructionHeader).isEqualTo(enablementInstructions[0]) - assertThat(dialog()?.instructions) - .isEqualTo(enablementInstructions.subList(1, enablementInstructions.size)) + assertThat(dialog()?.icon).isEqualTo(FakeKeyguardQuickAffordanceProviderClient.ICON_1) + assertThat(dialog()?.instructions).isEqualTo(enablementInstructions) assertThat(dialog()?.actionText).isEqualTo(enablementActionText) assertThat(dialog()?.intent?.`package`).isEqualTo(packageName) assertThat(dialog()?.intent?.action).isEqualTo(action) |