I am trying to use preferences in my UI to get values from the user and to fill into an object. Hence I do not wish to persist them. I created a custom TimePeriodPreference to get a time interval.
1) Why are the number pickers in my custom dialog preference missing the familiar +- controls? Furthermore, they do not allow input of text.
2) When (in which method) should I access the number pickers to harvest the values okay'ed? onDialogClosed() is too late. It gives me a null pointer error as the widgets are apparently lost by then.
04-23 13:09:04.732: E/AndroidRuntime(9794): java.lang.NullPointerException
04-23 13:09:04.732: E/AndroidRuntime(9794): at com.mypreferences.TimePeriodPreference.onDialogClosed(TimePeriodPreference.java:52)
04-23 13:09:04.732: E/AndroidRuntime(9794): at android.preference.DialogPreference.onDismiss(DialogPreference.java:382)
04-23 13:09:04.732: E/AndroidRuntime(9794): at android.app.Dialog$ListenersHandler.handleMessage(Dialog.java:1235)
FYI, complete code is here https://www.dropbox.com/s/pul1eximvsfxsvz/DataManagementPreferenceActivity.zip
I followed the steps here: http://developer.android.com/guide/topics/ui/settings.html#Custom
and also here: Concise way of writing new DialogPreference classes?
Trying to move it here following the example here, also causes a null pointer
@Override
protected View onCreateDialogView() {
hourPicker = (NumberPicker) getDialog().findViewById(R.id.hour_picker);
minPicker = (NumberPicker) getDialog().findViewById(R.id.min_picker);
return super.onCreateDialogView();
}
Note the missing +- controls
time_preference.xml
<TextView
android:id="@+id/textView5"
android:layout_width="wrap_content"
android:layout_height="38dp"
android:gravity="bottom"
android:text="remind every"
android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<NumberPicker
android:id="@+id/hour_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hr"
android:textAppearance="?android:attr/textAppearanceMedium" />
<NumberPicker
android:id="@+id/min_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Min"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
TimePeriodPreference.java
public class TimePeriodPreference extends DialogPreference {
int intervalLength = 0;
public TimePeriodPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setDialogLayoutResource(R.layout.time_preference);
setPositiveButtonText(android.R.string.ok);
setNegativeButtonText(android.R.string.cancel);
setDialogIcon(null);
setPersistent(false);
}
void setValue(int intervalLength) {
NumberPicker hourPicker, minPicker;
hourPicker = (NumberPicker) getDialog().findViewById(R.id.hour_picker);
short hours = (short) (intervalLength / 60);
hourPicker.setValue(hours);
minPicker = (NumberPicker) getDialog().findViewById(R.id.min_picker);
short minutes = (short) (intervalLength % 60);
minPicker.setValue(minutes);
}
void setDefaultValues() {
NumberPicker hourPicker, minPicker;
hourPicker = (NumberPicker) getDialog().findViewById(R.id.hour_picker);
hourPicker.setMinValue(0);
hourPicker.setMaxValue(23);
hourPicker.setValue(0);
minPicker = (NumberPicker) getDialog().findViewById(R.id.min_picker);
minPicker.setMinValue(0);
minPicker.setMaxValue(59);
minPicker.setValue(0);
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
// When the user selects "OK", persist the new value
if (positiveResult) {
NumberPicker hourPicker, minPicker;
hourPicker = (NumberPicker) getDialog().findViewById(R.id.hour_picker);
short hours = (short) ((NumberPicker) hourPicker).getValue();
minPicker = (NumberPicker) getDialog().findViewById(R.id.min_picker);
short minutes = (short) ((NumberPicker) minPicker).getValue();
intervalLength = hours * 60 + minutes;
}
}
@Override
protected View onCreateDialogView() {
return super.onCreateDialogView();
}
@Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
setDefaultValues();
intervalLength = (Integer) defaultValue;
}
/* (non-Javadoc)
* @see android.preference.DialogPreference#onBindDialogView(android.view.View)
*/
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
}
}
EditAlertPreferencesActivity.java
public class EditAlertPreferencesActivity extends Activity {
private static final String DISPLAY_MESSAGE = "display_msg";
private static final String ALERT_TYPE = "alert_type";
private static final String INTERVAL = "interval";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_prefs_fragment);
}
// Fragment that displays the mesg preference
public static class UserPreferenceFragment extends PreferenceFragment {
protected static final String TAG = "REGU";
private OnSharedPreferenceChangeListener mListener;
private Preference showMsgPreference;
private Preference alertTypePreference;
private Preference intervalPreference;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.user_prefs);
// Get the msg Preference
showMsgPreference = (Preference) getPreferenceManager()
.findPreference(DISPLAY_MESSAGE);
alertTypePreference = (Preference) getPreferenceManager()
.findPreference(ALERT_TYPE);
intervalPreference = (Preference) getPreferenceManager()
.findPreference(INTERVAL);
// Attach a listener to update summary when msg changes
mListener = new OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(
SharedPreferences sharedPreferences, String key) {
showMsgPreference.setSummary(sharedPreferences.getString(
DISPLAY_MESSAGE, "None Set"));
alertTypePreference.setSummary(sharedPreferences.getString(
ALERT_TYPE, "regular intervals or one time"));
intervalPreference.setSummary(sharedPreferences.getString(
INTERVAL, "-1"));
}
};
// Get SharedPreferences object managed by the PreferenceManager for
// this Fragment
SharedPreferences prefs = getPreferenceManager()
.getSharedPreferences();
// Register a listener on the SharedPreferences object
prefs.registerOnSharedPreferenceChangeListener(mListener);
// Invoke callback manually to display the msg
mListener.onSharedPreferenceChanged(prefs, DISPLAY_MESSAGE);
mListener.onSharedPreferenceChanged(prefs, ALERT_TYPE);
mListener.onSharedPreferenceChanged(prefs, INTERVAL);
}
}
}
user_prefs_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.mypreferences.EditAlertPreferencesActivity$UserPreferenceFragment"
android:orientation="vertical"
android:id="@+id/userPreferenceFragment">
</fragment>