commit 2c67a14f5a0a94e346e7acc14abb356ac53827b7 parent 583a99adcaf89a624fda2c8a675628f21a7de74f Author: iorgamgabriel <iorgamgabriel@yahoo.com> Date: Mon, 3 Nov 2025 07:30:04 +0000 Bug 1996458 - Show a MaterialAlertDialog for EditTextPreference. r=android-reviewers,007 Differential Revision: https://phabricator.services.mozilla.com/D270655 Diffstat:
6 files changed, 92 insertions(+), 0 deletions(-)
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/PreferenceFragmentExtensions.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/PreferenceFragmentExtensions.kt @@ -0,0 +1,55 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +package org.mozilla.fenix.settings + +import android.widget.EditText +import android.widget.FrameLayout +import androidx.preference.EditTextPreference +import androidx.preference.Preference +import androidx.preference.PreferenceFragmentCompat +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.mozilla.fenix.R + +/** + * Displays a custom [MaterialAlertDialogBuilder] for an [EditTextPreference]. + * This provides a consistent look and feel for text input dialogs across different settings screens. + * + * @param preference The [Preference] that was clicked. + * @param onSuccess An optional lambda to execute custom actions after the value is successfully changed. + * @return `true` if the dialog was handled for an [EditTextPreference], `false` otherwise. + */ +fun PreferenceFragmentCompat.showCustomEditTextPreferenceDialog( + preference: Preference, + onSuccess: () -> Unit = {}, +): Boolean { + if (preference !is EditTextPreference) { + return false + } + + val context = requireContext() + val editText = EditText(context).apply { + setText(preference.text) + } + + val container = FrameLayout(context).apply { + val horizontalPadding = context.resources.getDimensionPixelSize(R.dimen.dialog_edit_text_horizontal_padding) + setPadding(horizontalPadding, 0, horizontalPadding, 0) + addView(editText) + } + + MaterialAlertDialogBuilder(context) + .setTitle(preference.dialogTitle ?: preference.title) + .setView(container) + .setPositiveButton(android.R.string.ok) { _, _ -> + val newValue = editText.text.toString() + if (preference.callChangeListener(newValue)) { + preference.text = newValue + onSuccess() + } + } + .setNegativeButton(android.R.string.cancel, null) + .show() + + return true +} diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt @@ -372,4 +372,12 @@ class SecretSettingsFragment : PreferenceFragmentCompat() { } return super.onPreferenceTreeClick(preference) } + + override fun onDisplayPreferenceDialog(preference: Preference) { + val handled = showCustomEditTextPreferenceDialog(preference) + + if (!handled) { + super.onDisplayPreferenceDialog(preference) + } + } } diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SponsoredStoriesSettingsFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SponsoredStoriesSettingsFragment.kt @@ -60,4 +60,12 @@ class SponsoredStoriesSettingsFragment : PreferenceFragmentCompat() { scrollToPreference(it) } } + + override fun onDisplayPreferenceDialog(preference: Preference) { + val handled = showCustomEditTextPreferenceDialog(preference) + + if (!handled) { + super.onDisplayPreferenceDialog(preference) + } + } } diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SyncDebugFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SyncDebugFragment.kt @@ -36,6 +36,17 @@ class SyncDebugFragment : PreferenceFragmentCompat() { showToolbar(getString(R.string.preferences_sync_debug)) } + override fun onDisplayPreferenceDialog(preference: Preference) { + val handled = showCustomEditTextPreferenceDialog(preference) { + hasChanges = true + updateMenu() + } + + if (!handled) { + super.onDisplayPreferenceDialog(preference) + } + } + override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.sync_debug_preferences, rootKey) requirePreference<EditTextPreference>(R.string.pref_key_override_fxa_server).let { pref -> diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/account/AccountSettingsFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/account/AccountSettingsFragment.kt @@ -55,6 +55,7 @@ import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.settings.requirePreference +import org.mozilla.fenix.settings.showCustomEditTextPreferenceDialog @SuppressWarnings("TooManyFunctions", "LargeClass") class AccountSettingsFragment : PreferenceFragmentCompat() { @@ -259,6 +260,14 @@ class AccountSettingsFragment : PreferenceFragmentCompat() { ) } + override fun onDisplayPreferenceDialog(preference: Preference) { + val handled = showCustomEditTextPreferenceDialog(preference) + + if (!handled) { + super.onDisplayPreferenceDialog(preference) + } + } + /** * Prompts the user if they do not have a password/pin set up to secure their device, and * updates the state of the sync engine with the new checkbox value. diff --git a/mobile/android/fenix/app/src/main/res/values/dimens.xml b/mobile/android/fenix/app/src/main/res/values/dimens.xml @@ -49,6 +49,7 @@ <dimen name="top_bar_alignment_margin_start">72dp</dimen> <dimen name="top_bar_no_icon_alignment_margin_start">16dp</dimen> <dimen name="section_header_height">48dp</dimen> + <dimen name="dialog_edit_text_horizontal_padding">20dp</dimen> <!--Quick Settings--> <dimen name="quicksettings_item_height">48dp</dimen>