Loading res/layout/modes_edit_name.xml +26 −12 Original line number Diff line number Diff line Loading @@ -15,23 +15,37 @@ limitations under the License. --> <!-- Theme.AppCompat.DayNight is in the parent View so that it's merged with the Theme.Settings theme below. An AppCompat descendant (which Theme.Settings isn't is necessary to inflate TextInputLayout. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/Theme.AppCompat.DayNight" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" android:paddingBottom="8dp"> android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"> <EditText <com.google.android.material.textfield.TextInputLayout android:id="@+id/edit_input_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/Theme.Settings" style="?attr/textInputFilledStyle" app:endIconMode="clear_text" app:errorEnabled="true" android:hint="@string/zen_mode_edit_name_hint"> <com.google.android.material.textfield.TextInputEditText android:id="@android:id/edit" android:minHeight="48dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:maxLines="1" android:inputType="text|textCapSentences" android:imeOptions="actionDone" android:selectAllOnFocus="true" android:hint="@string/zen_mode_edit_name_hint" /> android:selectAllOnFocus="true" /> </com.google.android.material.textfield.TextInputLayout> </LinearLayout> res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -9585,6 +9585,9 @@ <!-- Modes: Hint for the EditText for editing a mode's name [CHAR LIMIT=30] --> <string name="zen_mode_edit_name_hint">Mode name</string> <!-- Modes: Error message when editing a mode's name and the name is empty [CHAR LIMIT=40] --> <string name="zen_mode_edit_name_empty_error">Mode name cannot be empty</string> <!-- Modes: Text shown above the list of icons in the mode editor. [CHAR LIMIT=40] --> <string name="zen_mode_edit_choose_icon_title">Choose an icon</string> res/values/themes.xml +3 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,9 @@ <item name="notification_importance_button_background_color_selected">?androidprv:attr/materialColorSecondaryContainer</item> <item name="notification_importance_button_border_color_selected">?androidprv:attr/materialColorOnSecondaryContainer</item> <item name="notification_importance_button_foreground_color_selected">?androidprv:attr/materialColorOnSecondaryContainer</item> <!-- For AppCompat widgets, e.g. TextInputLayout --> <item name="colorAccent">?android:attr/colorAccent</item> </style> <!-- Variant of the settings theme with no action bar. --> Loading src/com/android/settings/notification/modes/ZenModeEditNamePreferenceController.java +23 −3 Original line number Diff line number Diff line Loading @@ -17,9 +17,11 @@ package com.android.settings.notification.modes; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import android.content.Context; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.widget.EditText; Loading @@ -28,14 +30,18 @@ import androidx.annotation.Nullable; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settingslib.notification.modes.ZenMode; import com.android.settingslib.widget.LayoutPreference; import com.google.android.material.textfield.TextInputLayout; import java.util.function.Consumer; class ZenModeEditNamePreferenceController extends AbstractZenModePreferenceController { private final Consumer<String> mModeNameSetter; @Nullable private TextInputLayout mInputLayout; @Nullable private EditText mEditText; private boolean mIsSettingText; Loading @@ -50,7 +56,8 @@ class ZenModeEditNamePreferenceController extends AbstractZenModePreferenceContr super.displayPreference(screen); if (mEditText == null) { LayoutPreference pref = checkNotNull(screen.findPreference(getPreferenceKey())); mEditText = pref.findViewById(android.R.id.edit); mInputLayout = checkNotNull(pref.findViewById(R.id.edit_input_layout)); mEditText = checkNotNull(pref.findViewById(android.R.id.edit)); mEditText.addTextChangedListener(new TextWatcher() { @Override Loading @@ -61,9 +68,11 @@ class ZenModeEditNamePreferenceController extends AbstractZenModePreferenceContr @Override public void afterTextChanged(Editable s) { if (!mIsSettingText) { mModeNameSetter.accept(s.toString()); if (mIsSettingText) { return; } mModeNameSetter.accept(s.toString()); updateErrorState(s.toString()); } }); } Loading @@ -79,9 +88,20 @@ class ZenModeEditNamePreferenceController extends AbstractZenModePreferenceContr if (!modeName.equals(currentText)) { mEditText.setText(modeName); } updateErrorState(modeName); } finally { mIsSettingText = false; } } } private void updateErrorState(String currentName) { checkState(mInputLayout != null); if (TextUtils.isEmpty(currentName)) { mInputLayout.setError( mContext.getString(R.string.zen_mode_edit_name_empty_error)); } else { mInputLayout.setError(null); } } } tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceControllerTest.java +21 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ import com.android.settingslib.notification.modes.TestModeBuilder; import com.android.settingslib.notification.modes.ZenMode; import com.android.settingslib.widget.LayoutPreference; import com.google.android.material.textfield.TextInputLayout; import org.junit.Before; import org.junit.Rule; import org.junit.Test; Loading @@ -55,6 +57,7 @@ public class ZenModeEditNamePreferenceControllerTest { private ZenModeEditNamePreferenceController mController; private LayoutPreference mPreference; private TextInputLayout mTextInputLayout; private EditText mEditText; @Mock private Consumer<String> mNameSetter; Loading @@ -64,12 +67,15 @@ public class ZenModeEditNamePreferenceControllerTest { Context context = RuntimeEnvironment.application; PreferenceManager preferenceManager = new PreferenceManager(context); // Inflation is a test in itself, because it will crash if the Theme isn't set correctly. PreferenceScreen preferenceScreen = preferenceManager.inflateFromResource(context, R.xml.modes_edit_name_icon, null); mPreference = preferenceScreen.findPreference("name"); mController = new ZenModeEditNamePreferenceController(context, "name", mNameSetter); mController.displayPreference(preferenceScreen); mTextInputLayout = mPreference.findViewById(R.id.edit_input_layout); mEditText = mPreference.findViewById(android.R.id.edit); assertThat(mEditText).isNotNull(); } Loading @@ -88,11 +94,24 @@ public class ZenModeEditNamePreferenceControllerTest { public void onEditText_callsNameSetter() { ZenMode mode = new TestModeBuilder().setName("A fancy name").build(); mController.updateState(mPreference, mode); EditText editText = mPreference.findViewById(android.R.id.edit); editText.setText("An even fancier name"); mEditText.setText("An even fancier name"); verify(mNameSetter).accept("An even fancier name"); verifyNoMoreInteractions(mNameSetter); } @Test public void onEditText_emptyText_showsError() { ZenMode mode = new TestModeBuilder().setName("Default name").build(); mController.updateState(mPreference, mode); mEditText.setText(""); assertThat(mTextInputLayout.getError()).isNotNull(); mEditText.setText("this is fine"); assertThat(mTextInputLayout.getError()).isNull(); } } Loading
res/layout/modes_edit_name.xml +26 −12 Original line number Diff line number Diff line Loading @@ -15,23 +15,37 @@ limitations under the License. --> <!-- Theme.AppCompat.DayNight is in the parent View so that it's merged with the Theme.Settings theme below. An AppCompat descendant (which Theme.Settings isn't is necessary to inflate TextInputLayout. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/Theme.AppCompat.DayNight" android:paddingStart="?android:attr/listPreferredItemPaddingStart" android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" android:paddingBottom="8dp"> android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"> <EditText <com.google.android.material.textfield.TextInputLayout android:id="@+id/edit_input_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/Theme.Settings" style="?attr/textInputFilledStyle" app:endIconMode="clear_text" app:errorEnabled="true" android:hint="@string/zen_mode_edit_name_hint"> <com.google.android.material.textfield.TextInputEditText android:id="@android:id/edit" android:minHeight="48dp" android:layout_width="match_parent" android:layout_height="wrap_content" android:maxLines="1" android:inputType="text|textCapSentences" android:imeOptions="actionDone" android:selectAllOnFocus="true" android:hint="@string/zen_mode_edit_name_hint" /> android:selectAllOnFocus="true" /> </com.google.android.material.textfield.TextInputLayout> </LinearLayout>
res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -9585,6 +9585,9 @@ <!-- Modes: Hint for the EditText for editing a mode's name [CHAR LIMIT=30] --> <string name="zen_mode_edit_name_hint">Mode name</string> <!-- Modes: Error message when editing a mode's name and the name is empty [CHAR LIMIT=40] --> <string name="zen_mode_edit_name_empty_error">Mode name cannot be empty</string> <!-- Modes: Text shown above the list of icons in the mode editor. [CHAR LIMIT=40] --> <string name="zen_mode_edit_choose_icon_title">Choose an icon</string>
res/values/themes.xml +3 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,9 @@ <item name="notification_importance_button_background_color_selected">?androidprv:attr/materialColorSecondaryContainer</item> <item name="notification_importance_button_border_color_selected">?androidprv:attr/materialColorOnSecondaryContainer</item> <item name="notification_importance_button_foreground_color_selected">?androidprv:attr/materialColorOnSecondaryContainer</item> <!-- For AppCompat widgets, e.g. TextInputLayout --> <item name="colorAccent">?android:attr/colorAccent</item> </style> <!-- Variant of the settings theme with no action bar. --> Loading
src/com/android/settings/notification/modes/ZenModeEditNamePreferenceController.java +23 −3 Original line number Diff line number Diff line Loading @@ -17,9 +17,11 @@ package com.android.settings.notification.modes; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; import android.content.Context; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; import android.widget.EditText; Loading @@ -28,14 +30,18 @@ import androidx.annotation.Nullable; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import com.android.settings.R; import com.android.settingslib.notification.modes.ZenMode; import com.android.settingslib.widget.LayoutPreference; import com.google.android.material.textfield.TextInputLayout; import java.util.function.Consumer; class ZenModeEditNamePreferenceController extends AbstractZenModePreferenceController { private final Consumer<String> mModeNameSetter; @Nullable private TextInputLayout mInputLayout; @Nullable private EditText mEditText; private boolean mIsSettingText; Loading @@ -50,7 +56,8 @@ class ZenModeEditNamePreferenceController extends AbstractZenModePreferenceContr super.displayPreference(screen); if (mEditText == null) { LayoutPreference pref = checkNotNull(screen.findPreference(getPreferenceKey())); mEditText = pref.findViewById(android.R.id.edit); mInputLayout = checkNotNull(pref.findViewById(R.id.edit_input_layout)); mEditText = checkNotNull(pref.findViewById(android.R.id.edit)); mEditText.addTextChangedListener(new TextWatcher() { @Override Loading @@ -61,9 +68,11 @@ class ZenModeEditNamePreferenceController extends AbstractZenModePreferenceContr @Override public void afterTextChanged(Editable s) { if (!mIsSettingText) { mModeNameSetter.accept(s.toString()); if (mIsSettingText) { return; } mModeNameSetter.accept(s.toString()); updateErrorState(s.toString()); } }); } Loading @@ -79,9 +88,20 @@ class ZenModeEditNamePreferenceController extends AbstractZenModePreferenceContr if (!modeName.equals(currentText)) { mEditText.setText(modeName); } updateErrorState(modeName); } finally { mIsSettingText = false; } } } private void updateErrorState(String currentName) { checkState(mInputLayout != null); if (TextUtils.isEmpty(currentName)) { mInputLayout.setError( mContext.getString(R.string.zen_mode_edit_name_empty_error)); } else { mInputLayout.setError(null); } } }
tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceControllerTest.java +21 −2 Original line number Diff line number Diff line Loading @@ -35,6 +35,8 @@ import com.android.settingslib.notification.modes.TestModeBuilder; import com.android.settingslib.notification.modes.ZenMode; import com.android.settingslib.widget.LayoutPreference; import com.google.android.material.textfield.TextInputLayout; import org.junit.Before; import org.junit.Rule; import org.junit.Test; Loading @@ -55,6 +57,7 @@ public class ZenModeEditNamePreferenceControllerTest { private ZenModeEditNamePreferenceController mController; private LayoutPreference mPreference; private TextInputLayout mTextInputLayout; private EditText mEditText; @Mock private Consumer<String> mNameSetter; Loading @@ -64,12 +67,15 @@ public class ZenModeEditNamePreferenceControllerTest { Context context = RuntimeEnvironment.application; PreferenceManager preferenceManager = new PreferenceManager(context); // Inflation is a test in itself, because it will crash if the Theme isn't set correctly. PreferenceScreen preferenceScreen = preferenceManager.inflateFromResource(context, R.xml.modes_edit_name_icon, null); mPreference = preferenceScreen.findPreference("name"); mController = new ZenModeEditNamePreferenceController(context, "name", mNameSetter); mController.displayPreference(preferenceScreen); mTextInputLayout = mPreference.findViewById(R.id.edit_input_layout); mEditText = mPreference.findViewById(android.R.id.edit); assertThat(mEditText).isNotNull(); } Loading @@ -88,11 +94,24 @@ public class ZenModeEditNamePreferenceControllerTest { public void onEditText_callsNameSetter() { ZenMode mode = new TestModeBuilder().setName("A fancy name").build(); mController.updateState(mPreference, mode); EditText editText = mPreference.findViewById(android.R.id.edit); editText.setText("An even fancier name"); mEditText.setText("An even fancier name"); verify(mNameSetter).accept("An even fancier name"); verifyNoMoreInteractions(mNameSetter); } @Test public void onEditText_emptyText_showsError() { ZenMode mode = new TestModeBuilder().setName("Default name").build(); mController.updateState(mPreference, mode); mEditText.setText(""); assertThat(mTextInputLayout.getError()).isNotNull(); mEditText.setText("this is fine"); assertThat(mTextInputLayout.getError()).isNull(); } }