我正在尝试在我的UI中使用首选项来从用户获取值并填充到对象中。因此,我不想坚持他们。我创建了一个自定义的TimePeriodPreference来获取时间间隔。
1)为什么我的自定义对话框偏好中的数字选择器缺少熟悉的+控件?此外,他们不允许输入文本。
2)何时(在哪种方法中)我应该访问号码选择器来收获价值好吗? onDialogClosed()为时已晚。它给了我一个空指针错误,因为那时小部件显然丢失了。
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)
仅供参考,完整的代码在这里 https://www.dropbox.com/s/pul1eximvsfxsvz/DataManagementPreferenceActivity.zip
我按照这里的步骤操作: http://developer.android.com/guide/topics/ui/settings.html#Custom
也在这里: Concise way of writing new DialogPreference classes?
尝试按照示例here移动它,也会导致空指针
@Override
protected View onCreateDialogView() {
hourPicker = (NumberPicker) getDialog().findViewById(R.id.hour_picker);
minPicker = (NumberPicker) getDialog().findViewById(R.id.min_picker);
return super.onCreateDialogView();
}
注意缺少的+ - 控件
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>
答案 0 :(得分:2)
When (in which method) should I access the number pickers to harvest the values okay'ed?
您的TimePeriodPreference
课程需要像这样实施DialogInterface.OnClickListener
和Override
onClick
方法。
Override
public void onClick(DialogInterface dialog, int which){
if(which == DialogInterface.BUTTON_POSITIVE) {
// do your stuff to handle positive button
}else if(which == DialogInterface.BUTTON_NEGATIVE){
// do your stuff to handle negative button
}
}
然后,您可以在点击Ok
按钮(BUTTON_POSITIVE)
时访问数字选择器。
编辑:
Why are the number pickers in my custom dialog preference missing the familiar +- controls?
您需要像这样为选择器设置最大值和最小值,以显示增量和减量值。
NumberPicker np = (NumberPicker)findViewById(R.id.picker);
np.setMaxValue(100);
np.setMinValue(0);
您需要在onCreateDialogView
中设置选择器的默认值。只有在这里才会创建对话框视图。
@Override
protected View onCreateDialogView() {
View dialogView = super.onCreateDialogView();
// set the default values to the view
NumberPicker hourPicker = (NumberPicker) dialogView.findViewById(R.id.hour_picker);
hourPicker.setMinValue(0);
hourPicker.setMaxValue(23);
return dialogView;
}
注意:getDialog()仅在您显示对话框时才有效。