问题
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