Android Validating routine for EditTextPreference

我的未来我决定 提交于 2019-12-11 07:57:52

问题


I am a small step for completing the validation routine of a numeric preference.
I replaced the EditTextPrefernce OK button onClickListener to prevent leaving the dialog if the entry is not numeric.
I use TextWatcher.afterTextChanged to check if the entry is numeric or not, and I put the valid assesment on an EditText tag.
All is working well, pressing OK when the entry is invalid does not leave the dialog, pressing OK when the entry is valid...here I need to call the original OK button onClick, but I did not find how to do it. There are View functions callOnClick() and performOnClick(), but I looked into their code and they are meant to call the installed listener, not the original one.

@Override
public void onCreate(Bundle savedInstanceState) {
    Log.d(TAG, "+ onCreate(savedInstanceState:" + savedInstanceState + ")");
    super.onCreate(savedInstanceState);

    ...

    prefMaxLogs = (EditTextPreference) findPreference(getText(R.string.pref_maxLogs_key));
    prefMaxLogsEt = prefMaxLogs.getEditText();
    prefMaxLogsEt.setSingleLine();
    prefMaxLogsEt.setOnFocusChangeListener(ofcl);
    prefMaxLogsEt.addTextChangedListener(tw);

    ...

    Log.d(TAG, "- onCreate()");
}

private OnFocusChangeListener ofcl = new OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        Log.d(TAG, "+ onFocusChange(v:" + v + ", hasFocus:" + hasFocus + ")");
        if( hasFocus ) {
            prefMaxLogsEt.selectAll();
            Dialog dialog = prefMaxLogs.getDialog();
            if( dialog != null ) {
                dialog.findViewById(android.R.id.button1).setOnClickListener(ocl);
            }
        }
        Log.d(TAG, "- onFocusChange()");
    }
};

private OnClickListener ocl = new OnClickListener() {
    @Override
    public void onClick(View v) {
        Log.d(TAG, "+ onClick(v:" + v + ")");
        Boolean valid = !(Boolean) prefMaxLogsEt.getTag(R.string.invalidEntry);
        if( valid ) {
            Log.d(TAG, "Valid et");
        } 
        Log.d(TAG, "- onClick()");
    }
};

private TextWatcher tw = 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 s) {
        Log.d(TAG, "+ afterTextChanged(s:" + s + ")");
        String source = s.toString();
        //prefMaxLogsEt.removeTextChangedListener(this);
        if( !source.matches("^[0-9]+$") ) {
            prefMaxLogsEt.getBackground().setColorFilter(getResources().getColor(R.color.invalid), Mode.SRC_IN);
            prefMaxLogsEt.invalidate();
            prefMaxLogsEt.setError(getText(R.string.invalidEntry));
            prefMaxLogsEt.selectAll();
            prefMaxLogsEt.setTag(R.string.invalidEntry, true);
        } else {
            prefMaxLogsEt.setError(null);
            prefMaxLogsEt.getBackground().clearColorFilter();
            prefMaxLogsEt.invalidate();
            prefMaxLogsEt.setTag(R.string.invalidEntry, false);
        }
        //prefMaxLogsEt.addTextChangedListener(this);
        Log.d(TAG, "- afterTextChanged()");
    }
};

The onClickListener is set when the EditText gets focus, because I know the dialog is already showing.
The onClickListener prevents the dialog from closing with invalid entries


回答1:


I found a different way to validate the EditTextPreference. Setting OnPreferenceChangeListener and implementing onPreferenceChange.

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
    Log.d(TAG, "+ onPreferenceChange(preference:" + preference + ", newValue:" + newValue + ")");
    Boolean rv = true;
    if( preference.equals(prefMaxLogs) ) {
        String source = newValue.toString();
        if( !source.matches("^[0-9]+$") ) {
            rv = false;
        }
    }
    Log.d(TAG, "- onPreferenceChange()");
    return rv;
}

This function has the advantage that it returns a boolean value, true if you accept the changes, false if you reject them.
I dropped the onFocusListener and onClickListener for the OK button, this way is simpler.
I still use setColorFilter and afterTextChanged to warn the user on invalid entries. If the user presses OK, the dialog will close but only a valid value will be accepted.

This listener is set individually for each preference so this is my initialization in onCreate()

    prefMaxLogs = (EditTextPreference) findPreference(getText(R.string.pref_maxLogs_key));
    prefMaxLogsEt = prefMaxLogs.getEditText();
    prefMaxLogsEt.setSingleLine();
    prefMaxLogsEt.addTextChangedListener(tcl);
    prefMaxLogs.setOnPreferenceClickListener(this);


来源:https://stackoverflow.com/questions/15024692/android-validating-routine-for-edittextpreference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!