【问题标题】:Android date picker fragment change to spinnerAndroid 日期选择器片段更改为微调器
【发布时间】:2021-02-10 18:47:17
【问题描述】:

我正在尝试将日期选择器样式更改为一个日期选择器的微调器,其他日期选择器应保持默认。

我试过了:

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) 创建一些覆盖,在其中选择日期,但未填充覆盖值。

如何使用充气器更改日期选择器样式?

注意...我不能:

  • 更改样式,因为我还需要“常规”日期选择器。
  • 使用新的 Activity,我想坚持使用 Fragments。

谢谢!

【问题讨论】:

    标签: java android datepicker


    【解决方案1】:

    根本原因: DatePickerDialog 类有一个名为 mDatePicker 的 final 字段,该字段在构造函数中被初始化一次,所以当你调用时。

    final DatePickerDialog datePickerDialog = new DatePickerDialog(getActivity(), this, c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DAY_OF_MONTH));
    

    从那时起,mDatePicker 字段不能重新分配给任何值,因为它的修改是 final。当您在对话框上调用 setView 时,它只是更改对话框的视图,而不知道自定义布局中的 datePicker

    这解释了为什么当您更改自定义布局上的日期并点击 OK 按钮时,它会收集 mDatePicker 的值以返回您的片段,而不是自定义布局中的 datePicker

    解决方案 1: 使用自定义样式将日期选择器模式更改为微调器,但需要最低 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 类中

    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: 使用自定义布局文件创建自己的自定义日期选择器片段,适用于所有 API

    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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-12
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      相关资源
      最近更新 更多