AndroidX-自定义DialogPreference教程

AndroidX中自定义DialogPreference和android framework以及support库的不太一样,翻了官网文档发现也没有介绍,网上几乎也搜索不到相关资料,于是只能翻了sdk源代码来寻找方法,特此记录,给有需要的同学。

案例

做一个设置界面,其中有一个设置项是用来选择时间,因为界面选择了PreferenceFragmentCompat,所以最佳的做法就是自定义一个Preference,使得点击之后弹出一个TimePicker用来选择时间。于是定下目标,自定义类TimePickerPreference,实现点击弹出时间选择界面并自动保存值的效果。

实践

要完成任务,我们需要实现三个类,才能达到效果。

TimePickerPreference

在AndroidX中,官方把Preference的UI和数据部分分离了开来,而TimePickerPreference就是用来处理数据存储读取的。TimePickerPreference继承自androidx.preference.DialogPreference

    public void setTime(int time) {
        final boolean wasBlocking = shouldDisableDependents();

        timeInMinute = time;

        persistInt(time);

        final boolean isBlocking = shouldDisableDependents();
        if (isBlocking != wasBlocking) {
            notifyDependencyChange(isBlocking);
        }

        showSummary();
        notifyChanged();
    }

    public int getTime() {
        return timeInMinute;
    }

    @Override
    protected Object onGetDefaultValue(TypedArray a, int index) {
        return a.getInt(index, 0);
    }

    @Override
    protected void onSetInitialValue(Object defaultValue) {
        if (defaultValue == null)
            defaultValue = 0;
        setTime(getPersistedInt((Integer) defaultValue));
    }

注意上面代码中的两个Override方法,这就是必须要实现的两个方法,当然,还有其它方法,比如onSaveInstanceState之类的方法,文章最后会给出完整的源代码。

TimePickerDialogFragmentCompat

TimePickerDialogFragmentCompat负责UI层的构建,继承自androidx.preference.PreferenceDialogFragmentCompat

    @Override
    protected void onBindDialogView(View view) {
        super.onBindDialogView(view);
        picker = view.findViewById(R.id.time_picker);
        picker.setIs24HourView(true);

        picker.setCurrentHour(timeInMinute / 60);
        picker.setCurrentMinute(timeInMinute % 60);
    }

    private TimePickerPreference getTimePickerPreference() {
        return (TimePickerPreference) getPreference();
    }

    @Override
    public void onDialogClosed(boolean positiveResult) {
        if (positiveResult) {
            final TimePickerPreference preference = getTimePickerPreference();
            timeInMinute = calCurrentTime();
            if (preference.callChangeListener(timeInMinute)) {
                preference.setTime(timeInMinute);
            }
        }
    }

同样注意上面代码中的两个Override方法,这就是必须要实现的两个方法,当然,也有其它方法,比如同样的onSaveInstanceState之类的方法。注意,由于是负责构建UI的部分,其实它就是一个fragment,所以同样的,最好写一个newInstance方法用来构造对象,这样系统恢复此实例时会自动恢复其中的argument。文章的最后会给出完整的源代码。

MainFragment

最后就是我们用来展示自定义preference的界面了,假设叫MainFragment,继承自androidx.preference.PreferenceFragmentCompat,只要复写其中的一个方法就可以了。

    @Override
    public void onDisplayPreferenceDialog(Preference preference) {
        if (preference instanceof TimePickerPreference) {
            TimePickerDialogFragmentCompat f = TimePickerDialogFragmentCompat.newInstance(preference.getKey());
            f.setTargetFragment(this, 0);
            f.show(getFragmentManager(), TimePickerDialogFragmentCompat.FRAGMENT_TAG);
            return;
        }
        super.onDisplayPreferenceDialog(preference);
    }

大功告成


完整源码:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值