Android 日期选择器片段更改为微调器
Android date picker fragment change to spinner
我正在尝试将一个日期选择器的日期选择器样式更改为微调器,其他的将保持默认。
我试过:
public static class DatePickerFragment extends DialogFragment
implements DatePickerDialog.OnDateSetListener {
private int style;
DatePickerFragment(int xml) {
style = xml;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Calendar c = Calendar.getInstance();
final DatePickerDialog datePickerDialog = new DatePickerDialog(getActivity(), this, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
LayoutInflater inflater = requireActivity().getLayoutInflater();
datePickerDialog.setView(inflater.inflate(style, null));
return datePickerDialog;
}
@Override
public void onDateSet(DatePicker view, int year, int month, int day) {
Log.i("DatePicker", "received date from picker: " + day + "." + month + "." + year);
}
}
风格XML:
<?xml version="1.0" encoding="utf-8"?>
<DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/datePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:datePickerMode="spinner"
android:calendarViewShown="false" />
但是每当我在微调器中输入日期并点击确定时,当前(今天)日期就会记录在 onDateSet
方法中,而不是日期选择器中选择的日期。
我还尝试用以下方法覆盖 OK 按钮:
datePickerDialog.setButton(DialogInterface.BUTTON_POSITIVE, "asd", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Log.i("DatePicker", "received date from picker2: " + datePickerDialog.getDatePicker().getDayOfMonth() + "." + datePickerDialog.getDatePicker().getMonth()+1 + "." + datePickerDialog.getDatePicker().getYear());
}
});
但没有变化。
根据我的理解和行为,我正在使用 inflater.inflate(style, null)
创建一些叠加层,其中我 select 日期,但未填充叠加层值。
如何使用 inflater 更改日期选择器样式?
注意...我不能:
- 更改样式,因为我还需要“常规”日期选择器。
- 使用新的Activity,我想坚持使用片段。
谢谢!
根本原因: DatePickerDialog class 有一个名为 mDatePicker
的最终字段,这个字段在构造函数中初始化一次,所以当你调用.
final DatePickerDialog datePickerDialog = new DatePickerDialog(getActivity(), this, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
从那时起,mDatePicker
字段不能 re-assigned 为任何值,因为它的修改是 final
。当您在对话框上调用 setView
时,它只是更改对话框的视图,而不知道自定义布局中的 datePicker
。
这解释了为什么当您更改自定义布局上的日期并点击“确定”按钮时,它会将 mDatePicker
的值收集到 return 您的片段而不是您自定义中的 datePicker
布局。
解决方案 1:使用自定义样式将日期选择器模式更改为微调器,但需要 min API 21
第 1 步:在 styles.xml 文件中定义样式
<style name="customDatePickerStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:datePickerStyle">@style/customDatePicker</item>
</style>
<style name="customDatePicker" parent="@android:style/Widget.Material.Light.DatePicker">
<item name="android:datePickerMode">spinner</item>
<item name="android:calendarViewShown">false</item>
</style>
第 2 步:在 DatePickerFragment 中 class
public class DatePickerFragment extends DialogFragment
implements DatePickerDialog.OnDateSetListener {
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Calendar calendar = Calendar.getInstance();
return new DatePickerDialog(requireActivity(),
R.style.customDatePickerStyle,
this,
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH));
}
@Override
public void onDateSet(DatePicker view, int year, int month, int day) {
Log.i("DatePicker", "received date from picker: " + day + "." + month + "." + year);
}
}
解决方案 2: 使用自定义布局文件创建自己的自定义日期选择器片段,适用于所有 APIs
public class DatePickerFragment extends DialogFragment
implements DialogInterface.OnClickListener {
private int style;
private DatePicker mDatePicker;
DatePickerFragment(int xml) {
style = xml;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = requireActivity().getLayoutInflater().inflate(style, null);
Calendar calendar = Calendar.getInstance();
mDatePicker = view.findViewById(R.id.datePicker);
mDatePicker.init(calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
null);
return new AlertDialog.Builder(requireActivity())
.setView(view)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
mDatePicker.clearFocus();
onDateSet(mDatePicker,
mDatePicker.getYear(),
mDatePicker.getMonth(),
mDatePicker.getDayOfMonth());
break;
case DialogInterface.BUTTON_NEGATIVE:
dialog.dismiss();
break;
}
}
public void onDateSet(DatePicker view, int year, int month, int day) {
Log.i("DatePicker", "received date from picker: " + day + "." + month + "." + year);
}
}
我正在尝试将一个日期选择器的日期选择器样式更改为微调器,其他的将保持默认。
我试过:
public static class DatePickerFragment extends DialogFragment
implements DatePickerDialog.OnDateSetListener {
private int style;
DatePickerFragment(int xml) {
style = xml;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Calendar c = Calendar.getInstance();
final DatePickerDialog datePickerDialog = new DatePickerDialog(getActivity(), this, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
LayoutInflater inflater = requireActivity().getLayoutInflater();
datePickerDialog.setView(inflater.inflate(style, null));
return datePickerDialog;
}
@Override
public void onDateSet(DatePicker view, int year, int month, int day) {
Log.i("DatePicker", "received date from picker: " + day + "." + month + "." + year);
}
}
风格XML:
<?xml version="1.0" encoding="utf-8"?>
<DatePicker xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/datePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:datePickerMode="spinner"
android:calendarViewShown="false" />
但是每当我在微调器中输入日期并点击确定时,当前(今天)日期就会记录在 onDateSet
方法中,而不是日期选择器中选择的日期。
我还尝试用以下方法覆盖 OK 按钮:
datePickerDialog.setButton(DialogInterface.BUTTON_POSITIVE, "asd", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Log.i("DatePicker", "received date from picker2: " + datePickerDialog.getDatePicker().getDayOfMonth() + "." + datePickerDialog.getDatePicker().getMonth()+1 + "." + datePickerDialog.getDatePicker().getYear());
}
});
但没有变化。
根据我的理解和行为,我正在使用 inflater.inflate(style, null)
创建一些叠加层,其中我 select 日期,但未填充叠加层值。
如何使用 inflater 更改日期选择器样式?
注意...我不能:
- 更改样式,因为我还需要“常规”日期选择器。
- 使用新的Activity,我想坚持使用片段。
谢谢!
根本原因: DatePickerDialog class 有一个名为 mDatePicker
的最终字段,这个字段在构造函数中初始化一次,所以当你调用.
final DatePickerDialog datePickerDialog = new DatePickerDialog(getActivity(), this, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
从那时起,mDatePicker
字段不能 re-assigned 为任何值,因为它的修改是 final
。当您在对话框上调用 setView
时,它只是更改对话框的视图,而不知道自定义布局中的 datePicker
。
这解释了为什么当您更改自定义布局上的日期并点击“确定”按钮时,它会将 mDatePicker
的值收集到 return 您的片段而不是您自定义中的 datePicker
布局。
解决方案 1:使用自定义样式将日期选择器模式更改为微调器,但需要 min API 21
第 1 步:在 styles.xml 文件中定义样式
<style name="customDatePickerStyle" parent="Theme.AppCompat.Light.Dialog.Alert">
<item name="android:datePickerStyle">@style/customDatePicker</item>
</style>
<style name="customDatePicker" parent="@android:style/Widget.Material.Light.DatePicker">
<item name="android:datePickerMode">spinner</item>
<item name="android:calendarViewShown">false</item>
</style>
第 2 步:在 DatePickerFragment 中 class
public class DatePickerFragment extends DialogFragment
implements DatePickerDialog.OnDateSetListener {
@NonNull
@Override
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Calendar calendar = Calendar.getInstance();
return new DatePickerDialog(requireActivity(),
R.style.customDatePickerStyle,
this,
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH));
}
@Override
public void onDateSet(DatePicker view, int year, int month, int day) {
Log.i("DatePicker", "received date from picker: " + day + "." + month + "." + year);
}
}
解决方案 2: 使用自定义布局文件创建自己的自定义日期选择器片段,适用于所有 APIs
public class DatePickerFragment extends DialogFragment
implements DialogInterface.OnClickListener {
private int style;
private DatePicker mDatePicker;
DatePickerFragment(int xml) {
style = xml;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View view = requireActivity().getLayoutInflater().inflate(style, null);
Calendar calendar = Calendar.getInstance();
mDatePicker = view.findViewById(R.id.datePicker);
mDatePicker.init(calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
calendar.get(Calendar.DAY_OF_MONTH),
null);
return new AlertDialog.Builder(requireActivity())
.setView(view)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, this)
.create();
}
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
mDatePicker.clearFocus();
onDateSet(mDatePicker,
mDatePicker.getYear(),
mDatePicker.getMonth(),
mDatePicker.getDayOfMonth());
break;
case DialogInterface.BUTTON_NEGATIVE:
dialog.dismiss();
break;
}
}
public void onDateSet(DatePicker view, int year, int month, int day) {
Log.i("DatePicker", "received date from picker: " + day + "." + month + "." + year);
}
}