您的位置:首页 > 移动开发 > Android开发

Android日期时间选择器实现以及自定义大小

2014-11-10 20:40 786 查看
原文地址: http://lovelease.iteye.com/blog/2109729
本文主要讲两个内容:1.如何将DatePicker和TimePicker放在一个dialog里面;2.改变他们的宽度;

问题1:其实现思路就是自定义一个Dialog,然后往里面同时放入DatePicker和TimePicker,直接贴代码:

date_time_picker.xml:

Xml代码


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:gravity="center"

android:orientation="horizontal" >

<!-- <DatePicker

android:id="@+id/new_act_date_picker"

android:layout_width="0dip"

android:layout_height="wrap_content"

android:layout_weight="0.6"

android:calendarViewShown="false" />

<TimePicker

android:id="@+id/new_act_time_picker"

android:layout_width="0dip"

android:layout_height="wrap_content"

android:layout_weight="0.3"/> -->

<DatePicker

android:id="@+id/new_act_date_picker"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:calendarViewShown="false" />

<TimePicker

android:id="@+id/new_act_time_picker"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

</LinearLayout>

然后在需要显示日期时间选择器的地方(一般是一个onClickListener中)实例化dialog:

DemoActivity.java

Java代码


arriveAtBtn.setOnClickListener(new View.OnClickListener(){

@SuppressLint("NewApi")

@Override

public void onClick(View v) {

View view = View.inflate(getApplicationContext(), R.layout.date_time_picker, null);

final DatePicker datePicker = (DatePicker)view.findViewById(R.id.new_act_date_picker);

final TimePicker timePicker = (TimePicker)view.findViewById(R.id.new_act_time_picker);

// Init DatePicker

int year;

int month;

int day;

if (StringUtils.isEmpty(arriveDateBtn.getText().toString())) {

// Use the current date as the default date in the picker

final Calendar c = Calendar.getInstance();

year = c.get(Calendar.YEAR);

month = c.get(Calendar.MONTH);

day = c.get(Calendar.DAY_OF_MONTH);

} else {

year = NewActActivity.arrive_year;

month = NewActActivity.arrive_month;

day = NewActActivity.arrive_day;

}

datePicker.init(year, month, day, null);

// Init TimePicker

int hour;

int minute;

if (StringUtils.isEmpty(arriveTimeBtn.getText().toString())) {

// Use the current time as the default values for the picker

final Calendar c = Calendar.getInstance();

hour = c.get(Calendar.HOUR_OF_DAY);

minute = c.get(Calendar.MINUTE);

} else {

hour = NewActActivity.arrive_hour;

minute = NewActActivity.arrive_min;

}

timePicker.setIs24HourView(true);

timePicker.setCurrentHour(hour);

timePicker.setCurrentMinute(minute);

// Build DateTimeDialog

AlertDialog.Builder builder = new AlertDialog.Builder(NewActActivity.this);

builder.setView(view);

builder.setTitle(R.string.new_act_date_time_picker_title);

builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

arrive_year = datePicker.getYear();

arrive_month = datePicker.getMonth();

arrive_day = datePicker.getDayOfMonth();

String dateStr = DateUtil.formatDate(arrive_year, arrive_month, arrive_day);

arriveDateBtn.setText(dateStr);

arrive_hour = timePicker.getCurrentHour();

arrive_min = timePicker.getCurrentMinute();

String timeStr = DateUtil.formatTime(arrive_hour, arrive_min);

arriveTimeBtn.setText(timeStr);

}

});

builder.show();

}

});

这样就可以实现日期时间选择器了,这里就有点layout上的小问题,你是需要datepicker和timepicker水平排列还是竖直排列,竖直排列是没问题的:下面给出两个数值排列的效果图:

(1)DatePicker控件中设置android:calendarViewShown="false" 时的效果图:



(2)(1)DatePicker控件中设置android:spinnersShown="false" 时的效果图:



当然,如果你android:calendarViewShown和android:spinnersShown都不设置为false的话,会同时显示日历和滚动条样式,我想一般不会有人想要这样的视图吧。

水平排列是有问题的,那就是屏幕太挤,两个控件显示不全,看看效果图:



可是有人就是有水平排列的需求怎么办?这就是本文要讲的第二个问题:改变datepicker和timepicker的宽度。

网上找了很久,没有发现很有效的方法,说是这两个控件的子元素的宽度是不能自定义的,实际上把控件的所有属性看了一遍,也确实没有发现相关的属性;有人是通过自定义DatePicker和TimePicker来实现的,找了个demo,确实是实现了,不过已经相当于是自己写了一个插件了,我嫌麻烦,加之稳定性方面的考虑,没有去用,不过我会在最后把这个demo的src带上,有需要的人可以自己下载来研究。难道真不能改宽度吗?突然想到我是不是能从代码中的datePicker对象一步步往下找到其child,直接改child的宽度呢,于是debug,果然通过这种方式成功改变了宽度值,代码如下,只要在DemoActivity.java中增加一块专门用于实现改宽度的代码就行:

DemoActivity.java:

Java代码


arriveAtBtn.setOnClickListener(new View.OnClickListener(){

@SuppressLint("NewApi")

@Override

public void onClick(View v) {

View view = View.inflate(getApplicationContext(), R.layout.date_time_picker, null);

final DatePicker datePicker = (DatePicker)view.findViewById(R.id.new_act_date_picker);

final TimePicker timePicker = (TimePicker)view.findViewById(R.id.new_act_time_picker);

// Change DatePicker layout

LinearLayout dpContainer = (LinearLayout)datePicker.getChildAt(0) ; // LinearLayout

LinearLayout dpSpinner = (LinearLayout)dpContainer.getChildAt(0); // 0 : LinearLayout; 1 : CalendarView

for(int i = 0; i < dpSpinner.getChildCount(); i ++) {

NumberPicker numPicker = (NumberPicker)dpSpinner.getChildAt(i); // 0-2 : NumberPicker

LayoutParams params1 = new LayoutParams(120, LayoutParams.WRAP_CONTENT);

params1.leftMargin = 0;

params1.rightMargin = 30;

numPicker.setLayoutParams(params1);

// EditText cusET = (EditText)numPicker.getChildAt(0); // CustomEditText

// cusET.setTextSize(14);

// cusET.setWidth(70);

}

// Change TimePicker layout

LinearLayout tpContainer = (LinearLayout)timePicker.getChildAt(0) ; // LinearLayout

LinearLayout tpSpinner = (LinearLayout)tpContainer.getChildAt(0); // 0 : LinearLayout; 1 : CalendarView

for(int i = 0; i < tpSpinner.getChildCount(); i ++) {

// child(1) is a TextView ( : )

if (i == 1) {

continue;

}

NumberPicker numPicker = (NumberPicker)tpSpinner.getChildAt(i); // 0 : NumberPicker; 1 : TextView; 2 : NumberPicker

LayoutParams params3 = new LayoutParams(100, LayoutParams.WRAP_CONTENT);

params3.leftMargin = 0;

params3.rightMargin = 30;

numPicker.setLayoutParams(params3);

// EditText cusET = (EditText)numPicker.getChildAt(0); // CustomEditText

// cusET.setTextSize(14);

// cusET.setWidth(70);

}

// Init DatePicker

int year;

int month;

int day;

if (StringUtils.isEmpty(arriveDateBtn.getText().toString())) {

// Use the current date as the default date in the picker

final Calendar c = Calendar.getInstance();

year = c.get(Calendar.YEAR);

month = c.get(Calendar.MONTH);

day = c.get(Calendar.DAY_OF_MONTH);

} else {

year = NewActActivity.arrive_year;

month = NewActActivity.arrive_month;

day = NewActActivity.arrive_day;

}

datePicker.init(year, month, day, null);

// Init TimePicker

int hour;

int minute;

if (StringUtils.isEmpty(arriveTimeBtn.getText().toString())) {

// Use the current time as the default values for the picker

final Calendar c = Calendar.getInstance();

hour = c.get(Calendar.HOUR_OF_DAY);

minute = c.get(Calendar.MINUTE);

} else {

hour = NewActActivity.arrive_hour;

minute = NewActActivity.arrive_min;

}

timePicker.setIs24HourView(true);

timePicker.setCurrentHour(hour);

timePicker.setCurrentMinute(minute);

// Build DateTimeDialog

AlertDialog.Builder builder = new AlertDialog.Builder(NewActActivity.this);

builder.setView(view);

builder.setTitle(R.string.new_act_date_time_picker_title);

builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

arrive_year = datePicker.getYear();

arrive_month = datePicker.getMonth();

arrive_day = datePicker.getDayOfMonth();

String dateStr = DateUtil.formatDate(arrive_year, arrive_month, arrive_day);

arriveDateBtn.setText(dateStr);

arrive_hour = timePicker.getCurrentHour();

arrive_min = timePicker.getCurrentMinute();

String timeStr = DateUtil.formatTime(arrive_hour, arrive_min);

arriveTimeBtn.setText(timeStr);

}

});

builder.show();

}

});

通过这种方式实现的效果图如下:



其实这种方法也有问题:我的手机是1080P(5.5寸)的屏,显示效果是这样,如果屏幕小点,分辨率更低的屏呢,很可能屏幕宽度不够显示,当然你可以修改一下上面代码的逻辑,根据屏幕大小来动态设置控件的宽度值,而不是设成定值,具体的这些细节按自己的需求来做吧,我这里只是想记录一下自己发现的这种改变datepicker和timepicker宽度的方法,至于是否实用,我不负责,我只当是学习一下android。不过我的项目里最终没有用这个方案,最终选择了垂直排列的日历格式那个方案。

最后附上别人实现的自定义DatePicker和TimePicker(MyPicker)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: