网上有很多优秀的开源时间控件,可以满足我们大部分的需求。

但有时候还是会碰到系统自带的DatePicker,这个控件默认的月份显示为英文,如JANUARY、FEBRUARY等。

如何将月份由英文改成数字,这是个好玩的问题。

庖丁解牛

DatePicker并没有提供相关api可以实现我们的需求,所以需要我们自己来分析。

查看DatePicke的源码,它的布局文件是date_picker.xml,如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_gravity="center_horizontal"android:orientation="horizontal"android:gravity="center"><LinearLayout android:id="@+id/pickers"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:orientation="horizontal"android:gravity="center"><!-- Month --><NumberPicker
            android:id="@+id/month"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="1dip"android:layout_marginEnd="1dip"android:focusable="true"android:focusableInTouchMode="true"/><!-- Day --><NumberPicker
            android:id="@+id/day"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="1dip"android:layout_marginEnd="1dip"android:focusable="true"android:focusableInTouchMode="true"/><!-- Year --><NumberPicker
            android:id="@+id/year"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="1dip"android:layout_marginEnd="1dip"android:focusable="true"android:focusableInTouchMode="true"/></LinearLayout><!-- calendar view --><CalendarView
        android:id="@+id/calendar_view"android:layout_width="245dip"android:layout_height="280dip"android:layout_marginStart="44dip"android:layout_weight="1"android:focusable="true"android:focusableInTouchMode="true"android:visibility="gone"/></LinearLayout>

可以很轻松地发现,月份就是一个id为month的NumberPicker控件。

DatePicker中以month控件为线索,很快发现NumberPicker下的这个方法:

    /*** Sets the values to be displayed.** @param displayedValues The displayed values.*/public void setDisplayedValues(String[] displayedValues) {.........}

该方法参数为一个String数组,该数组每一项就是展示的月份数据。

所以如果我们自己调用该方法,传入以数字表示的月份,就达到目的啦!

寻找调用时机

DatePicker源码中,直接调用setDisplayedValues方法的地方有两处,

一处是在构造函数中:

public DatePicker(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);......OnValueChangeListener onChangeListener = new OnValueChangeListener() {public void onValueChange(NumberPicker picker, int oldVal, int newVal) {......updateSpinners();updateCalendarView();notifyDateChanged();}};......// monthmMonthSpinner = (NumberPicker) findViewById(R.id.month);mMonthSpinner.setMinValue(0);mMonthSpinner.setMaxValue(mNumberOfMonths - 1);mMonthSpinner.setDisplayedValues(mShortMonths);mMonthSpinner.setOnLongPressUpdateInterval(200);mMonthSpinner.setOnValueChangedListener(onChangeListener);mMonthSpinnerInput =(EditText)mMonthSpinner.findViewById(R.id.numberpicker_input);......
}

mShortMonths就是默认的英文月份,就不展开介绍了。

构造函数中在第X行调用了setDisplayedValues方法,完成了展示月份数据的设置。

同时mMonthSpinner的值监听器为onChangeListener,当月份变化时会回调onValueChange方法,该方法中又会调用updateSpinners方法,这是另一处直接调用setDisplayedValues方法的地方:

private void updateSpinners() {......// make sure the month names are a zero based array// with the months in the month spinnerString[] displayedValues = Arrays.copyOfRange(mShortMonths,mMonthSpinner.getMinValue(), mMonthSpinner.getMaxValue() + 1);mMonthSpinner.setDisplayedValues(displayedValues);......}

updateSpinners方法除了会在上述的监听器中被调用,还要其他方法中也会调用,例如:

    /*** Initialize the state. If the provided values designate an inconsistent* date the values are normalized before updating the spinners.** @param year The initial year.* @param monthOfYear The initial month <strong>starting from zero</strong>.* @param dayOfMonth The initial day of the month.* @param onDateChangedListener How user is notified date is changed by*            user, can be null.*/public void init(int year, int monthOfYear, int dayOfMonth,OnDateChangedListener onDateChangedListener) {setDate(year, monthOfYear, dayOfMonth);updateSpinners();updateCalendarView();mOnDateChangedListener = onDateChangedListener;}/*** Sets the maximal date supported by this {@link DatePicker} in* milliseconds since January 1, 1970 00:00:00 in* {@link TimeZone#getDefault()} time zone.** @param maxDate The maximal supported date.*/public void setMaxDate(long maxDate) {mTempDate.setTimeInMillis(maxDate);if (mTempDate.get(Calendar.YEAR) == mMaxDate.get(Calendar.YEAR)&& mTempDate.get(Calendar.DAY_OF_YEAR) != mMaxDate.get(Calendar.DAY_OF_YEAR)) {return;}mMaxDate.setTimeInMillis(maxDate);mCalendarView.setMaxDate(maxDate);if (mCurrentDate.after(mMaxDate)) {mCurrentDate.setTimeInMillis(mMaxDate.getTimeInMillis());updateCalendarView();}updateSpinners();}

以上所有直接或间接调用setDisplayedValues方法的地方都会将月份重置为英文显示,所以我们自己调用setDisplayedValues方法的时机就是在这些方法被调用之后。

也就是说,我们的调用时机在DatePicker构造函数之后、init()setMaxDate()等方法之后和onDateChanged()方法之中。

轻松实现

知道了在何时调用何方法后,我们来具体实现这一需求。

首先准备好展示的月份数组:

String months[] = {"1月", "2月", "3月", "4月", "5月", "6月","7月", "8月", "9月", "10月", "11月", "12月"};

假设mDatePicker就是目标DatePicker控件,因为DatePicker没有提供可以获取到月份控件的api,所以需要自己想办法获取到月份控件,再调用它的setDisplayedValues方法。

分析之前的date_picker.xml文件,可以写出下面这行代码:

((NumberPicker) ((ViewGroup) ((ViewGroup) mDatePicker.getChildAt(0)).getChildAt(0)).getChildAt(0)).setDisplayedValues(months);

通过调用这行代码,就实现了替换掉英文月份的目标!

Android原生时间控件DatePicker——月份由英文转数字相关推荐

  1. Android自定义时间控件不可选择未来时间

    本文出自:http://blog.csdn.net/dt235201314/article/details/78718066 Android自定义时间控件选择开始时间到结束时间 Android自定义时 ...

  2. 时间控件date-picker 时间差计算

    时间控件date-picker 例子 //加载时间控件 $('.date-picker').datepicker({ rtl: Metronic.isRTL(),//RTL:right to left ...

  3. Qt for Android调用android原生Toast控件

    用Qt开发Android应用,有时候会想着直接调用android原生的一些组件或者打开某些android的系统界面,比如调用Toast显示消息提醒.打开android系统设置页面.这里主要讲解如何通过 ...

  4. android实现左拉菜单,Android原生侧滑控件DrawerLayout使用方法详解

    在android的v4包中有一个控件 Drawerlayout,主要实现了左拉和右拉菜单,类似于之前的"抽屉"功能,此控件使用简单,效果很柔和,操作起来体验非常好,下面是我实现的一 ...

  5. Android卡片滑动切换动画,Android原生ViewPager控件实现卡片翻动效果

    本文实例为大家分享了Android控件ViewPager实现卡片翻动效果的具体代码,供大家参考,具体内容如下 先放一张效果图: 想要实现这样的效果其实并不是太难,需要对ViewPager的一些细节属性 ...

  6. android 自定义switch控件,Android中switch自定义样式

    android 原生开关按钮控件 Switch 提供样式自定义方式,可供我们修改为适合我们开发使用的样式控件,自定义样式过程如下: 自定义switch切换drawable 新建swith_thumb. ...

  7. Android开发之日期时间控件选择

    Android开发之日期时间控件选择 文章目录 前言 一.创建弹出Layout 1.1 新建Layout,修改样式为LinearLayout 1.2 Layout中添加日期和时间控件 二.新建Date ...

  8. android时间控件

    原文地址:http://www.360doc.com/content/14/0617/16/18203124_387517665.shtml 前言 这一篇博客分别讲解Android平台下,关于日期和时 ...

  9. veu中时间转换----element-UI上Date-Picker时间控件

    veu中时间转换 如果 this.startTime 为2020-09-20 则 new Date(this.startTime) // Sun Sep 20 2020 08:00:00 GMT+08 ...

最新文章

  1. 异常:android.os.NetworkOnMainThreadException
  2. 半平面交比较好的博客
  3. 独家 | 在树莓派+Movidius NCS上运用YOLO和Tiny-YOLO完成目标检测(附代码下载)
  4. 80 年代以来的操作系统 GUI 设计进化史
  5. java基础英语---第二十一天
  6. 百度翻译API的使用
  7. 《HTML 5与CSS 3权威指南 》 (第2版·下册)——第19章 19.3.2
  8. 11.5 vmstat:虚拟内存统计
  9. Android之使用HandlerThread 以及如何退出总结
  10. Django框架(展示图书信息简易版)
  11. ORACLE HANDBOOK系列之六:ODP.NET与复杂的PL/SQL数据类型(Using ODP.NET To Deal With Complex PLSQL Data Types)...
  12. 灵动标签调用栏目自定义字段
  13. java h5服务器推送事件_关于H5+中push推送的服务端代码是怎么写的
  14. mtk无线网卡 linux,Linux下安装MT7601U无线网卡驱动
  15. 咪咕:笔试题(20190916)
  16. linux scsi程序,Linux scsi设备读写流程
  17. ESP8266物联网开发入门教程
  18. 关于flask-sqlalchemy同字段多条件的过滤方法
  19. MOVS,LODS,CMPS,SCAS,STOS
  20. Python 二分查找:bisect库的使用

热门文章

  1. android+mmi是病毒?,恶意软件分析 URL链接扫描 免费在线病毒分析平台 | 魔盾安全分析...
  2. vue3.0+ts+wow.js+animate.css
  3. Linux 学习笔记 2022-11-12---------Linux基础
  4. 魅族升级鸿蒙,魅族升级鸿蒙,是蹭华为热度,还是布局未来?小米的态度透着精明...
  5. AndroidStudio 中A problem occurred evaluating project ‘:app‘. > No signature of method:报错
  6. redis(二)基本数据类型
  7. 获取分享社最新一期的迅雷分享账号
  8. 微信小程序预览服务器图片,微信小程序实现图片选择并预览功能
  9. Vue中作用域插槽solt详解
  10. 如何在3分钟内实现音频变声和趣味音效?