diff --git a/res/layout/modes_edit_name.xml b/res/layout/modes_edit_name.xml index 498fe4c2b2d..b888431a830 100644 --- a/res/layout/modes_edit_name.xml +++ b/res/layout/modes_edit_name.xml @@ -15,23 +15,37 @@ limitations under the License. --> + + android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"> - + android:theme="@style/Theme.Settings" + style="?attr/textInputFilledStyle" + app:endIconMode="clear_text" + app:errorEnabled="true" + android:hint="@string/zen_mode_edit_name_hint"> - \ No newline at end of file + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 294aae37cec..2d686a8b107 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -9585,6 +9585,9 @@ Mode name + + Mode name cannot be empty + Choose an icon diff --git a/res/values/themes.xml b/res/values/themes.xml index 64c8904550e..4f20d8c9091 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -73,6 +73,9 @@ ?androidprv:attr/materialColorSecondaryContainer ?androidprv:attr/materialColorOnSecondaryContainer ?androidprv:attr/materialColorOnSecondaryContainer + + + ?android:attr/colorAccent diff --git a/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceController.java b/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceController.java index 78cbfe0488b..6b490d6113d 100644 --- a/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceController.java @@ -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; @@ -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 mModeNameSetter; + @Nullable private TextInputLayout mInputLayout; @Nullable private EditText mEditText; private boolean mIsSettingText; @@ -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 @@ -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()); } }); } @@ -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); + } + } } diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceControllerTest.java index 795de505097..caaa1a55ffd 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeEditNamePreferenceControllerTest.java @@ -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; @@ -55,6 +57,7 @@ public class ZenModeEditNamePreferenceControllerTest { private ZenModeEditNamePreferenceController mController; private LayoutPreference mPreference; + private TextInputLayout mTextInputLayout; private EditText mEditText; @Mock private Consumer mNameSetter; @@ -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(); } @@ -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(); + } }