Подтверждение editTextPreference Android
Я прочитал много ответов на этот вопрос, но мой вопрос спрашивает, где я размещаю код. Я хочу подтвердить, что число больше 100 в edittextPreference
, Это код, который я использую для заполнения предпочтений:
public class SettingsFrag extends PreferenceFragment{
//Override onCreate so that the code will run when the activity is started.
@Override
public void onCreate(Bundle savedInstanceState){
//Call to the super class.
super.onCreate(savedInstanceState);
//add the preferences from the XML file.
addPreferencesFromResource(R.xml.preferences);
}
}
Здесь я добавляю валидацию или мне нужно создать другой класс?
preferences.xml:
<EditTextPreference
android:key="geofence_range"
android:title="Geofence Size"
android:defaultValue="500"
android:inputType="number"
android:summary="Geofence Size Around User Location"
android:dialogTitle="Enter Size (meters):" />
2 ответа
Добавлять setOnPreferenceChangeListener
за EditTextPreference
после addPreferencesFromResource
чтобы проверить ввод данных для пользователя:
EditTextPreference edit_Pref = (EditTextPreference)
getPreferenceScreen().findPreference("geofence_range");
edit_Pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// put validation here..
if(<validation pass>){
return true;
}else{
return false;
}
}
});
Да. Еще одна из тех вещей, которые должны быть чертовски просты в Android, но это не так. Другие ответы просто молча мешают записать результат в предпочтения, что кажется немного скучным. (Показ тоста менее дрянной, но все еще дрянной).
Вам понадобится пользовательское предпочтение, чтобы сделать это. Настройте onValidate в соответствии с вашими потребностями.
package com.two_play.extensions;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.EditText;
public class ValidatingEditTextPreference extends EditTextPreference {
public ValidatingEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
public ValidatingEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ValidatingEditTextPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ValidatingEditTextPreference(Context context) {
super(context);
}
@Override
protected void showDialog(Bundle state) {
super.showDialog(state);
AlertDialog dlg = (AlertDialog)getDialog();
View positiveButton = dlg.getButton(DialogInterface.BUTTON_POSITIVE);
getEditText().setError(null);
positiveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onPositiveButtonClicked(v);
}
});
}
private void onPositiveButtonClicked(View v) {
String errorMessage = onValidate(getEditText().getText().toString());
if (errorMessage == null)
{
getEditText().setError(null);
onClick(getDialog(),DialogInterface.BUTTON_POSITIVE);
getDialog().dismiss();
} else {
getEditText().setError(errorMessage);
return; // return WITHOUT dismissing the dialog.
}
}
/***
* Called to validate contents of the edit text.
*
* Return null to indicate success, or return a validation error message to display on the edit text.
*
* @param text The text to validate.
* @return An error message, or null if the value passes validation.
*/
public String onValidate(String text)
{
try {
Double.parseDouble(text);
return null;
} catch (Exception e)
{
return getContext().getString(R.string.error_invalid_number);
}
}
}
Мне кажется более элегантным отключить кнопку "ОК" вместо того, чтобы позволить пользователю нажимать ее, но затем отказаться от ввода и показать ошибку. getDialog
кажется, ушел androidx.preference
, но это, похоже, работает для меня:
final EditTextPreference p = new EditTextPreference(context);
p.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
@Override
public void onBindEditText(@NonNull final EditText editText) {
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable editable) {
String validationError;
try {
// ... insert your validation logic here, throw on failure ...
validationError = null; // All OK!
} catch (Exception e) {
validationError = e.getMessage();
}
editText.setError(validationError);
editText.getRootView().findViewById(android.R.id.button1)
.setEnabled(validationError == null);
}
});
}
});
Вот моя реализация Kotlin для androidx.preference.*
на основе ответа Владимира Пантелеева:
class CustomPreference : EditTextPreference {
// ...
private fun applyValidation() = setOnBindEditTextListener { editText ->
editText.doAfterTextChanged { editable ->
requireNotNull(editable)
// TODO Add validation magic here.
editText.error = if (criteria.isValid()) {
null // Everything is fine.
} else {
if (criteria.getErrorMessage() == null) "Unknown validation error"
else resources.getString(criteria.getErrorMessage())
}
}
}
}
Удобный
doAfterTextChanged
расширение является частью androidx.core:core-ktx
библиотека.