Ael
Ael

Reputation: 323

Any simple way to require an EditTextPreference value to not be blank in Android?

I have a number of EditTextPreference which must be a number 0-9. I can prevent other characters but not backspace. Backspace + Okay = an empty value. An empty value means when the it is retrieved and parsed into a number it will crash.

At the moment I check when a preference changes, if it has certain keys and no length, and if so, I re-save with a "0". Is there a simpler built in way to do this? A "require value" property, or at least something more automatic like being able to get the digits of the changed preference? (if digits is "0123456789" then it must not be empty).

So far in the settings activity I have:

public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    //Prevent EditText from being non number
    String type = this.findPreference(key).getClass().getSimpleName();
    if( type.equals("EditTextPreference")
        //Put key of any allowed to be blank here...
                && prefs.getString(key, "0").length()==0 ){ 
            this.findPreference(key).setSummary("0");

        SharedPreferences.Editor prefedit = prefs.edit();
        prefedit.putString(key, "0");
        prefedit.commit();
    }
    updateSummaries();
}

(Set summary isn't working --^. Being able to check the android:digits="0123456789" property would make it so I wouldn't need to put keys of any that should be blank.)

Or in the main activity I can put all of the numerical prefs into Strings, check the string, set it to 0 if no good, then parse each string. As I use more of them this feels less appealing, not automatic.

String sTT = prefs.getString("mykey", "0");
>> x10
if(sTT.length()==0){ sTT="0"; }
>> x10
tt = Long.parseLong( sTT );
>> x10, different types

(This may still be the best way...?)

Upvotes: 5

Views: 2895

Answers (4)

Linxy
Linxy

Reputation: 2635

A really easy way to is to simply override EditTextPreference like this.

public class SafeEditTextPreference extends EditTextPreference {

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public SafeEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public SafeEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public SafeEditTextPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public SafeEditTextPreference(Context context) {
        super(context);
    }


    @Override
    protected void onDialogClosed(boolean positiveResult) {
        boolean valid = this.getEditText().getText().toString().length() > 0;
        super.onDialogClosed(valid);
    }

}

Then use that instead of EditTextPreference. It will only save to preferences if the text string is at least 1 long, however you can change that validity check to be whatever you need it to be.

You could add a TextWatcher to give the user a more dynamic response.

Upvotes: 0

kunmi
kunmi

Reputation: 692

Really old, but just in case there;s someone having issues with this, This is what I usually do in such case,

have your Application class implemnt OnSharedPreferenceChangeListener, it'll look like this:

public class MyAppApplication extends Application implements
        OnSharedPreferenceChangeListener

Put this in oncreate, so you can actively keep watch on Menu updates anytime;

preference = PreferenceManager.getDefaultSharedPreferences(this);
        preference.registerOnSharedPreferenceChangeListener(this);

and you can do this in any suitable part in your Application class,

if (preference.getString("prefkey", "").compareTo("") == 0) {
            SharedPreferences.Editor temp = preference.edit();
            temp.putString("prefkey", defaultServerAddress);
            temp.apply();
        }

I do this in my OnCreate tho, so I whenever the app starts, the preference item in question is, always reverted.

You can also do smart moves in public void onSharedPreferenceChanged, to keep track of the possibility that the preference item has become blank.

Upvotes: 0

PearsonArtPhoto
PearsonArtPhoto

Reputation: 39698

You could always make a simple preferences class, which takes an EditText with android:inputType = "number"

Upvotes: 0

Graham Borland
Graham Borland

Reputation: 60681

You can apply a TextWatcher to the EditTextPreference's underlying EditText. This allows you to intercept any changes to the text, and modify it in any way you want, by forcing it to contain a default digit (0) for example.

Although, I think it would make more sense overall for you to just cope with an empty input when you parse the data.

Upvotes: 1

Related Questions