Android原生时间控件DatePicker——月份由英文转数字
来源:互联网 发布:拳皇2002出招优化补丁 编辑:程序博客网 时间:2024/05/24 03:52
网上有很多优秀的开源时间控件,可以满足我们大部分的需求。
但有时候还是会碰到系统自带的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(); } }; ...... // month mMonthSpinner = (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 spinner String[] 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——月份由英文转数字
- Android DatePicker控件获取时间月份少1
- Android 时间控件1.DatePicker
- 数字—英文月份
- android时间控件DatePicker使用实例
- android 控件 日期和时间(DatePicker,TimePicker)
- DatePicker时间控件
- Android开发——DatePicker和TimePicker时间选择器
- 一步一步学android控件(之十二) —— DatePicker
- android开发中DatePicker控件的使用-------->时间的设置
- Android之日期时间选择控件DatePicker和TimePicker
- android控件19 DatePicker
- Android控件 DatePicker
- DatePicker TimePicker---日期时间控件
- Jquery实现时间控件datepicker
- 时间控件的使用datePicker,
- 日期时间控件DatePicker,TimePicker
- ios Datepicker 把英文的月份改成中文 设置datepicker的大小
- docker 中不能用vim编辑文件
- 用Python学《微积分B》(不定积分的概念)
- 打印二叉树边界节点
- Python学习笔记(八)-- Python字典(Dictionary)
- sql之left join、right join、inner join的区别
- Android原生时间控件DatePicker——月份由英文转数字
- jquery获取checkbox 选中数量
- Java中static和final的区别
- HDU 1565 方格取数(1)(最大独立点集)
- 搜狐字符串abcde
- Windows环境的RabbitMQ之HelloWorld
- 关于微信分享
- [NOIP模拟](二)T1-操作
- Ubuntu用户和组管理