最近需要一个在让用户设置中设置时间的操作,发现网上的例子大多不能用了,于是自己写了一个供大家参考。


1.通过继承DialogPreference来实现点击该Preference后弹出带TimePicker的dialog。在构造方法中设定自定义的simpleSummaryProvider。
public class TimePickerPreference extends DialogPreference {
private String mText;
@Nullable
private OnBindTimePickerListener mOnBindTimePickerListener;
public TimePickerPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
setSummaryProvider(SimpleSummaryProvider.getInstance());
setDialogLayoutResource(R.layout.time_picker_dialog);
}
public TimePickerPreference(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
@SuppressLint("RestrictedApi")
public TimePickerPreference(Context context, AttributeSet attrs) {
this(context, attrs, TypedArrayUtils.getAttr(context, R.attr.dialogPreferenceStyle,
android.R.attr.dialogPreferenceStyle));
}
public TimePickerPreference(Context context) {
this(context, null);
}
public String getText() {
return mText;
}
@Override
public boolean shouldDisableDependents() {
return TextUtils.isEmpty(mText) || super.shouldDisableDependents();
}
public void setText(String text) {
final boolean wasBlocking = shouldDisableDependents();
mText = text;
persistString(text);
final boolean isBlocking = shouldDisableDependents();
if (isBlocking != wasBlocking) {
notifyDependencyChange(isBlocking);
}
notifyChanged();
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getString(index);
}
@Override
protected void onSetInitialValue(Object defaultValue) {
setText(getPersistedString((String) defaultValue));
}
public void setOnBindTimePickerListener(@Nullable OnBindTimePickerListener onBindTimePickerListener) {
mOnBindTimePickerListener = onBindTimePickerListener;
}
@Nullable
OnBindTimePickerListener getOnBindTimePickerListener() {
return mOnBindTimePickerListener;
}
public interface OnBindTimePickerListener {
void onBindTimePicker(@NonNull TimePicker timePicker);
}
public static final class SimpleSummaryProvider implements SummaryProvider<TimePickerPreference> {
private static SimpleSummaryProvider sSimpleSummaryProvider;
private SimpleSummaryProvider() {}
public static SimpleSummaryProvider getInstance() {
if (sSimpleSummaryProvider == null) {
sSimpleSummaryProvider = new SimpleSummaryProvider();
}
return sSimpleSummaryProvider;
}
@SuppressLint("PrivateResource")
@Override
public CharSequence provideSummary(TimePickerPreference preference) {
if (TextUtils.isEmpty(preference.getText())) {
return (preference.getContext().getString(R.string.not_set));
} else {
return preference.getText();
}
}
}
}
2.还需配套写一个继承PreferenceDialogFragmentCompat的类来负责弹出的对话框的逻辑。
public class DialogPrefFragCompat extends PreferenceDialogFragmentCompat {
private TimePicker mTimePicker;
private CharSequence mText;
public static DialogPrefFragCompat newInstance(String key) {
final DialogPrefFragCompat fragment = new DialogPrefFragCompat();
final Bundle bundle = new Bundle(1);
bundle.putString(ARG_KEY, key);
fragment.setArguments(bundle);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
mText = getTimePickerPreference().getText();
if(TextUtils.isEmpty(mText))
mText=getContext().getText(R.string.default_remind_time);
}
}
private TimePickerPreference getTimePickerPreference() {
return (TimePickerPreference) getPreference();
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
mTimePicker = view.findViewById(R.id.time_picker);
if (mTimePicker == null) {
throw new IllegalStateException("Dialog view must contain an TimePicker with id" +
" @android:id/time_picker");
}
String[] hourAndMinute= mText.toString().split(":");
int hour = Integer.parseInt(hourAndMinute[0]);
int minute = Integer.parseInt(hourAndMinute[1]);
mTimePicker.setCurrentHour(hour);
mTimePicker.setCurrentMinute(minute);
if (getTimePickerPreference().getOnBindTimePickerListener() != null) {
getTimePickerPreference().getOnBindTimePickerListener().onBindTimePicker(mTimePicker);
}
}
@Override
public void onDialogClosed(boolean positiveResult) {
if (positiveResult) {
int hour = mTimePicker.getCurrentHour();
int minute = mTimePicker.getCurrentMinute();
String value = String.format("%02d:%02d",hour,minute);
Toast.makeText(getContext(), value, Toast.LENGTH_SHORT).show();
final TimePickerPreference preference = getTimePickerPreference();
if (preference.callChangeListener(value)) {
preference.setText(value);
}
}
}
}
3.除此之外还需重写fragment页面的onDisplayPreferenceDialog方法来调用之前的PreferenceDialogFragmentCompat子类来生成dialog。
public class SettingsFragment extends PreferenceFragmentCompat{
...
@Override
public void onDisplayPreferenceDialog(Preference preference) {
if (preference instanceof TimePickerPreference) {
DialogFragment dialogFragment = DialogPrefFragCompat.newInstance(preference.getKey());
dialogFragment.setTargetFragment(this, 0);
dialogFragment.show(getParentFragmentManager(), null);//getFragmentManager()
} else super.onDisplayPreferenceDialog(preference);
}
...
}
4.布局参考
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/radial_time_picker"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TimePicker
android:id="@+id/time_picker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:timePickerMode="spinner"/>
</LinearLayout>
自定义TimePickerPreference实现
本文介绍了如何在Android应用中创建一个自定义的TimePickerPreference。通过继承DialogPreference并设置自定义simpleSummaryProvider,配合PreferenceDialogFragmentCompat子类处理对话框逻辑,以及重写onDisplayPreferenceDialog方法来显示对话框,实现用户设置时间的功能。
743

被折叠的 条评论
为什么被折叠?



