当用户编辑字段中的值时,自定义 DatePicker 作为首选项不会保留值

发布于 2024-10-04 05:15:04 字数 2994 浏览 6 评论 0原文

我创建了一个 DatePickerPreference,即我扩展了 DialogPreference 并在内部创建了一个 DatePicker 对象,并且让它几乎完美地工作。当您单击向上和向下箭头时,它会更改值并保存您选择的值。

但是,如果您单击字段内部并在其中键入新值,它不会保存更新的值!使用箭头时,始终会调用 onDateChanged() 方法;当用户输入字段并编辑它时,如果他选择另一个字段,它只会调用 onDateChanged (在这种情况下,如果他编辑最后一个字段并单击“确定”,则最后一次编辑将被忽略)。我发现 Eric Besette 发布了与他的 TimePickerPreference 类似的问题

这是我的代码:


    public class DatePickerPreference extends DialogPreference implements  
OnDateChangedListener, OnDateSetListener {

    @Override
    protected View onCreateDialogView() {
        DatePicker picker = new DatePicker(getContext());
        mDate = getPersistedLong(System.currentTimeMillis());

        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(mDate);

        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int month = calendar.get(Calendar.MONTH);
        int year = calendar.get(Calendar.YEAR);

        picker.init(year, month, day, this);
        return picker;
    }

    public void onDateChanged(DatePicker view, int year, int monthOfYear,  
            int dayOfMonth) {
        mDate = (new Date(year - 1900, monthOfYear, dayOfMonth)).getTime();
    }

    public void onDateSet(DatePicker view, int year, int monthOfYear,  
            int dayOfMonth) {
        onDateChanged(view, year, monthOfYear, dayOfMonth);
    }

    @Override
    public void setDefaultValue(Object defaultValue) {
        super.setDefaultValue(String.valueOf((  
            new Date(String.valueOf(defaultValue))).getTime()));
    }

    @Override
    protected void onDialogClosed(boolean positiveResult) {
        super.onDialogClosed(positiveResult);

        if(positiveResult) {
            if(isPersistent()) {
                persistLong(mDate);
            }
            callChangeListener(String.valueOf(mDate));
        }
    }

    public int getYear() { /*(...)*/ }
    public int getMonth() { /*(...)*/ }
    public int getDay() { /*(...)*/ }

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

    public DatePickerPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public void init() { setPersistent(true); }
    public void setDate(Date date) { mDate = date.getTime(); }
    public void setDate(long milisseconds) { mDate = milisseconds; }

    public String getDate(int style) {
        return DateFormat.getDateInstance(style).format(new Date(mDate));
    }

    public long getDate() { return mDate; }

    private long mDate;
    public static final int DATE_SHORT = DateFormat.SHORT;
    public static final int DATE_MEDIUM = DateFormat.MEDIUM;
    public static final int DATE_LONG = DateFormat.LONG;
    public static final int DATE_FULL = DateFormat.FULL;
    public static final int DATE_DEFAULT = DateFormat.DEFAULT;
}

I created a DatePickerPreference, i.e. I extended DialogPreference and created a DatePicker object inside and had it working almost perfectly. It changes values when you click the arrows up and down and saves the value you select.

However, if you click inside the field and types the new value there, it doesn't save the updated value! When using the arrows, the onDateChanged() method is always called; when user enters the field and edits it, it will only call onDateChanged if he selects another field (and in this case, if he edits the last field and just hit OK, the last edit will be ignored). I found that Eric Besette posted a similar problem with his TimePickerPreference

Here is my code:


    public class DatePickerPreference extends DialogPreference implements  
OnDateChangedListener, OnDateSetListener {

    @Override
    protected View onCreateDialogView() {
        DatePicker picker = new DatePicker(getContext());
        mDate = getPersistedLong(System.currentTimeMillis());

        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(mDate);

        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int month = calendar.get(Calendar.MONTH);
        int year = calendar.get(Calendar.YEAR);

        picker.init(year, month, day, this);
        return picker;
    }

    public void onDateChanged(DatePicker view, int year, int monthOfYear,  
            int dayOfMonth) {
        mDate = (new Date(year - 1900, monthOfYear, dayOfMonth)).getTime();
    }

    public void onDateSet(DatePicker view, int year, int monthOfYear,  
            int dayOfMonth) {
        onDateChanged(view, year, monthOfYear, dayOfMonth);
    }

    @Override
    public void setDefaultValue(Object defaultValue) {
        super.setDefaultValue(String.valueOf((  
            new Date(String.valueOf(defaultValue))).getTime()));
    }

    @Override
    protected void onDialogClosed(boolean positiveResult) {
        super.onDialogClosed(positiveResult);

        if(positiveResult) {
            if(isPersistent()) {
                persistLong(mDate);
            }
            callChangeListener(String.valueOf(mDate));
        }
    }

    public int getYear() { /*(...)*/ }
    public int getMonth() { /*(...)*/ }
    public int getDay() { /*(...)*/ }

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

    public DatePickerPreference(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public void init() { setPersistent(true); }
    public void setDate(Date date) { mDate = date.getTime(); }
    public void setDate(long milisseconds) { mDate = milisseconds; }

    public String getDate(int style) {
        return DateFormat.getDateInstance(style).format(new Date(mDate));
    }

    public long getDate() { return mDate; }

    private long mDate;
    public static final int DATE_SHORT = DateFormat.SHORT;
    public static final int DATE_MEDIUM = DateFormat.MEDIUM;
    public static final int DATE_LONG = DateFormat.LONG;
    public static final int DATE_FULL = DateFormat.FULL;
    public static final int DATE_DEFAULT = DateFormat.DEFAULT;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风蛊 2024-10-11 05:15:04

由于此类扩展了 DialogPreference 类,因此它已经处理使用按钮更改 SharedPreference 的情况。要在用户输入新日期后正确更新日期变量,您需要手动更新 SharedPreference

您可以按如下方式执行此操作:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor preferences = prefs.edit();
preferences.putLong("mdate_key", mDate.getTime());
preferences.commit();

此处,mdate_key 将对应于 PreferenceActivity XML 文件中使用的 DatePickerPreference 键。

我建议在 onDateChanged()onDestroy() 中执行此操作。

Since this class extends the DialogPreference class, it already handles changing the SharedPreference using the buttons. To correctly update your date variable after the user types the new date, you need to update the SharedPreference manually.

You can do this as follows:

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor preferences = prefs.edit();
preferences.putLong("mdate_key", mDate.getTime());
preferences.commit();

Here, mdate_key will correspond to the DatePickerPreference key used in the PreferenceActivity XML file.

I recommend either doing this in onDateChanged() or onDestroy().

江挽川 2024-10-11 05:15:04

我有同样的问题。解决方案非常简单。日期选择器仅在失去焦点时更新编辑的值,因此在获取值之前,您必须调用:

datePicker.clearFocus();

在此调用之后,您可以调用:

selectedDay = datePicker.getDayOfMonth();
selectedMonth = datePicker.getMonth();

并更新值。

I had the same issue. The solution is very simple. The date picker updates the edited values only when it losts focus, so before getting the values you have to call:

datePicker.clearFocus();

After this call you can call:

selectedDay = datePicker.getDayOfMonth();
selectedMonth = datePicker.getMonth();

and have the values updated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文