androidandroidxappcompatactivityedittextpreferenceimeoptions

AndroidX: Set Enter key to validate EditTextPreference dialog box


I'm trying to make a preference screen with AndroidX, but I'm encountering a small problem...

When I validate my entry with the "OK" button on the virtual keyboard, the preference is not validated. (keyboard is hidden, that's all...)

With AndroidX, we can no longer override showDialog() in EditTextPreference... and I couldn't find another way to access the dialog box to dismiss it.

In conclusion, what I wish: the DONE action of the button on the virtual keyboard validates the AlertDialog.

enter image description here

Here's my sample code:

XML file

<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
    <EditTextPreference
        app:key="pref_1"
        app:title="Test"
        app:useSimpleSummaryProvider="true" /> 
</PreferenceScreen> 

Preference activity

public class MySettingsActivity extends AppCompatActivity implements
        PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {

    [...]

    public static class HeaderFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            setPreferencesFromResource(R.xml.header_preferences, rootKey);

            EditTextPreference pref1 = getPreferenceManager().findPreference("pref_1");
            pref1.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
                @Override
                public void onBindEditText(@NonNull EditText editText) {
                    editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
                    editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
                }
            });
        }
    }
}

Solution

  • If you want to validate that update value of text you need to use this listener

    pref1.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
    
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    // put validation here..
    
                    Log.d("Prefrence====>",newValue+"<===  validate you can validate this value");
    
                    return true; //if you pass false here the updated value will not save
                }
            });
    

    here is the example to use the true false return

    public static class HeaderFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            setPreferencesFromResource(R.xml.headerpref, rootKey);
    
            EditTextPreference pref1 = getPreferenceManager().findPreference("pref_1");
    
            pref1.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
    
                @Override
                public boolean onPreferenceChange(Preference preference, Object newValue) {
                    // put validation here..
    
                    Log.d("Prefrence====>",newValue+"<===  validate you can validate this value");
                    if(newValue.toString().length()>0){
                        return  true;
                    }else return false;
                }
            });
    
            pref1.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
                @Override
                public void onBindEditText(@NonNull EditText editText) {
                    editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
                    editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
                    editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
                        @Override
                        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                            //Your dialog will dissmiss on ok click
                            if(actionId==EditorInfo.IME_ACTION_DONE)dismissDialog();
                            return false;
                        }
                    });
    
                }
            });
    
    
        }
    void dismissDialog(){
            for(Fragment fragments : HeaderFragment.this.getActivity().getSupportFragmentManager().getFragments()){
                if(fragments instanceof EditTextPreferenceDialogFragmentCompat){
                    EditTextPreferenceDialogFragmentCompat dialog = ((EditTextPreferenceDialogFragmentCompat) fragments);
                    dialog.onDialogClosed(true);
                    dialog.dismiss();
                    return;
                }
            }
        }
    }
    

    Since you want to dismiss Dialog manually you can do it like this way , cause there are no direct method available to get the dialog and dismiss it.

    I updated the dialog dismiss listener as your need to save the data passing true in onDialogClosed method will help to save your data

    void dismissDialog(){
    
            for(Fragment fragments : HeaderFragment.this.getActivity().getSupportFragmentManager().getFragments()){
                if(fragments instanceof EditTextPreferenceDialogFragmentCompat){
                    EditTextPreferenceDialogFragmentCompat dialog = ((EditTextPreferenceDialogFragmentCompat) fragments);
                    dialog.onDialogClosed(true);
                    dialog.dismiss();
                    return;
                }
            }
        }