问题
I have a TimePreference class that derives from DialogPreference. I'm using 3 NumberPicker to set hours, minutes and seconds. This works fine. But when onSetInitialValue is called defaultValue is always null. Whereas onGetDefaultValue returns the correct value that is defined in the preferences. Any ideas what is wrong?
public TimePreference(Context ctxt, AttributeSet attrs, int defStyle) {
super(ctxt, attrs, defStyle);
setPositiveButtonText(R.string.ok);
setNegativeButtonText(R.string.cancel);
setDialogLayoutResource(R.layout.time_preference_layout);
}
@Override
protected void onBindDialogView(View v) {
super.onBindDialogView(v);
mHoursPicker = (NumberPicker)v.findViewById(R.id.hours);
mHoursPicker.setMinValue(0);
mHoursPicker.setMaxValue(23);
mHoursPicker.setFormatter(TWO_DIGIT_FORMATTER);
mMinutesPicker = (NumberPicker)v.findViewById(R.id.minutes);
mMinutesPicker.setMinValue(0);
mMinutesPicker.setMaxValue(59);
mMinutesPicker.setFormatter(TWO_DIGIT_FORMATTER);
mSecondsPicker = (NumberPicker)v.findViewById(R.id.seconds);
mSecondsPicker.setMinValue(0);
mSecondsPicker.setMaxValue(59);
mSecondsPicker.setFormatter(TWO_DIGIT_FORMATTER);
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult) {
long currentTimeInMillis = convertTimeToMillis();
if (callChangeListener(currentTimeInMillis)) {
persistLong(currentTimeInMillis);
notifyChanged();
}
}
CharSequence summary = getSummary();
setSummary(summary);
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
super.onGetDefaultValue(a, index);
return a.getString(index);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
super.onSetInitialValue(restoreValue, defaultValue);
long value = 0;
if (restoreValue) {
if (defaultValue == null) {
Log.d( "bla", "No default value defined!");
} else {
value = Long.parseLong(getPersistedString((String) defaultValue));
}
} else {
if (defaultValue == null) {
Log.d( "bla", "No default value defined!");
} else {
value = Long.parseLong((String) defaultValue);
}
}
String result = convertMillisToTime(value);
setSummary(result);
}
@Override
public CharSequence getSummary() {
if (mHoursPicker == null) {
return null;
}
return convertTimeToString( mHoursPicker.getValue(), mMinutesPicker.getValue(), mSecondsPicker.getValue());
}
}
回答1:
Why don't you try setting the default value manually? If you are saving this time value to sharedPreferences, you can specify it in your xml declaration of a PreferenceScreen:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<PreferenceCategory
android:title="@string/pref_cat_general"
android:layout_width="match_parent"
android:layout_height="match_parent">
<to.marcus.rxtesting.ui.widgets.ChoicePreference
android:key="@string/pref_key_sel_time"
android:title="@string/pref_title_time"
android:summary="set time"/>
Notice the custom preference ChoicePreference. Once this is declared, you can define it in its own class, similarly to what you've done above by extending DialogPreference:
public class ChoicePreference extends DialogPreference {
public ChoicePreference(Context context, AttributeSet attrs){
super(context,attrs);
}
@Override
protected void onClick(){
AlertDialog.Builder dialog = new AlertDialog.Builder(getContext());
dialog.setTitle("Check Time");
dialog.setMessage("confirm time:");
dialog.setCancelable(true);
dialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(getContext(), "time set!", Toast.LENGTH_SHORT).show();
putPrefValue("key_sel_time",true);
}
});
The putPrefValue(key,value) method will write/overwrite your sharedPreference value:
private void putPrefValue(String key, boolean value){
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor editor = prefs.edit();
//removes existing key to trigger change listener
editor.remove(key);
editor.commit();
editor.putBoolean(key, value);
editor.apply();
}
Then from this point you'll need your Activity, for instance, to listen to these sharedPreference changes:
1.) set a listener variable for your sharedPrefs:
private static SharedPreferences sharedPrefs;
private static SharedPreferences.OnSharedPreferenceChangeListener mListener;
2.) register/unregister the listener
@Override
protected void onResume() {
super.onResume();
sharedPrefs.registerOnSharedPreferenceChangeListener(mListener);
}
@Override
protected void onPause() {
super.onPause();
sharedPrefs.unregisterOnSharedPreferenceChangeListener(mListener);
}
3.) get an instance and do something with the result/change
private void initSharedPrefsListener(){
sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
mListener = new SharedPreferences.OnSharedPreferenceChangeListener(){
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPrefs, String key){
mBasePresenterImpl.onPrefSelected(key, sharedPrefs.getString(key, "default value here"));
}
};
}
The onPrefSelected method here is conceptual. You can could take the resulting value and persist it to a JsonString.
来源:https://stackoverflow.com/questions/25004668/default-value-of-custom-dialogpreference-is-null