【问题标题】:Spinner DatePicker with numeric months instead of named带有数字月份而不是命名的 Spinner DatePicker
【发布时间】:2021-07-15 14:32:33
【问题描述】:

我有一个基本的DatePicker,它是微调器样式,没有任何布局。它看起来像这样:

class DatePickerFragment: DialogFragment(), DatePickerDialog.OnDateSetListener {

    private lateinit var date: Date

    interface Callbacks {
        fun onDateSelected(date: Date)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        date = arguments?.getSerializable(ARG_DATE) as Date
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val calendar = Calendar.getInstance().apply {
            time = date
        }

        val initialYear = calendar.get(Calendar.YEAR)
        val initialMonth = calendar.get(Calendar.MONTH)
        val initialDay = calendar.get(Calendar.DAY_OF_MONTH)

        return DatePickerDialog(
            requireContext(),
            this,
            initialYear,
            initialMonth,
            initialDay
        )
    }

    override fun onDateSet(view: DatePicker?, year: Int, month: Int, dayOfMonth: Int) {
        val selectedDate = GregorianCalendar(year, month, dayOfMonth).time
        targetFragment?.let { fragment ->
            (fragment as Callbacks).onDateSelected(selectedDate)
        }
    }

    companion object {
        fun getInstance(date: Date): DatePickerFragment {
            return DatePickerFragment().apply {
                arguments = Bundle().apply {
                    putSerializable(ARG_DATE, date)
                }
            }
        }
    }
}

private const val ARG_DATE = "date"

选择器正常工作。问题是它显示月份名称(三字母格式),见:

如何使 DatePicker 以数字方式显示月份(两位数格式)? 换句话说,它会显示为 03,而不是 Mar。理想情况下,如果可能的话,我希望避免实现自定义微调器。

【问题讨论】:

  • 截图会很有帮助,有什么以及你想要实现什么。我猜你想在日历上将 Mar 更改为 03 对吧?
  • @HappySingh 是的,没错。
  • @HappySingh DatePicker,确切地说是微调器,而不是日历视图。
  • 您需要获取月份选择器 ID。试试view?.findViewById<NumberPicker?>(resources.getIdentifier("android:id/month", null, null))?.displayedValues = arrayOf("01","02" ....)onDateChanged(...)
  • @StanislavBondar 不幸的是这不起作用。

标签: android kotlin android-datepicker


【解决方案1】:

您可以通过从 DatePicker 中找到月份 NumberPicker 并将显示的值设置为数字字符串来实现此目的。

进行以下更改:

1.使用如下自定义样式在onCreateDialog(savedInstanceState: Bundle?) 中创建您的 DatePickerDialog:

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val calendar = Calendar.getInstance().apply {
            time = date
        }

        val initialYear = calendar.get(Calendar.YEAR)
        val initialMonth = calendar.get(Calendar.MONTH)
        val initialDay = calendar.get(Calendar.DAY_OF_MONTH)

        val mPickerDialog: DatePickerDialog = object : DatePickerDialog(requireContext(), R.style.MyDatePickerDialogStyle, this, initialYear, initialMonth, initialDay) {
            override fun onDateChanged(view: DatePicker, year: Int, month: Int, dayOfMonth: Int) {
                super.onDateChanged(view, year, month, dayOfMonth)
                setNumericMonth(view)
            }
        }
        setNumericMonth(mPickerDialog.datePicker)
        return mPickerDialog
    }

R.style.MyDatePickerDialogStyle 是自定义样式,用于设置 Spinner 样式,如下所示:

<style name="MyDatePickerDialogStyle" parent="android:Theme.Material.Dialog">
      <item name="android:datePickerStyle">@style/MyDatePickerStyle</item>
</style>
    
<style name="MyDatePickerStyle" parent="android:Widget.Material.DatePicker">
     <item name="android:datePickerMode">spinner</item>
 </style>

2.使用DatePickerFragment中的以下辅助函数将月份设置为如下数字:

private fun setNumericMonth(datePicker: DatePicker) {
        val monthNumbers = arrayOf("01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12")
        val monthPicker = getMonthNumberPicker(datePicker)
        if (monthPicker != null) {
            monthPicker.displayedValues = monthNumbers
        }
    }

private fun getMonthNumberPicker(datePicker: DatePicker?): NumberPicker? {
        try {
            if (datePicker != null && datePicker.childCount > 0 && datePicker.getChildAt(0) is ViewGroup) {
                val vg = datePicker.getChildAt(0) as ViewGroup
                if (vg.childCount > 0 && vg.getChildAt(0) is ViewGroup) {
                    val vgPickers = vg.getChildAt(0) as ViewGroup
                    for (i in 0 until vgPickers.childCount) {
                        if (vgPickers.getChildAt(i) is NumberPicker && i == 1) {
                            return vgPickers.getChildAt(i) as NumberPicker
                        }
                    }
                }
            }
        } catch (e: Exception) {
        }
        return null
    }

结果:

【讨论】:

  • 我将不得不研究 getMonthNumberPicker() 在后台是如何工作的。但是您的解决方案有效,谢谢。
  • 不客气。 getMonthNumberPicker() 尝试查找作为 LinearLayout ViewGroup (vgPickers) 的子项的月份编号选择器。这个 LinearLayout 有 3 个 NumberPicker 子项,第一个是日期 NumberPicker,第二个是我们感兴趣的月份(代码中 i==1)和年份 NumberPicker。
猜你喜欢
  • 1970-01-01
  • 2011-03-13
  • 1970-01-01
  • 1970-01-01
  • 2020-04-03
  • 1970-01-01
  • 2022-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多