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

android日期选择控件DatePicker小结

2016-07-21 14:43 561 查看
更新:

通过为TimePicker控件增加属性,使其具有是否以当前时间为上限的属性设置。

1、在attrs.xml文件中增加:

<declare-styleable name="TimePicker">
<attr name="Timelimited" format="boolean"/>

</declare-styleable>


2、在需要使用TimePicker控件的xml中设置:

xmlns:timePicker="http://schemas.android.com/apk/res-auto"

并在控件处使用:

<com.xxx.pickerview.TimePicker
android:id="@+id/datepicker_start"
timePicker:Timelimited="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>


这样我们就能在TimePicker的构造函数中获取该属性并根据其值做相应操作:

比如下面的  flag  就是我们上面设置的属性值;

public TimePicker(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.TimePicker);
boolean flag = a.getBoolean(R.styleable.TimePicker_Timelimited,false);
LayoutInflater.from(context).inflate(R.layout.pickerview_time, this,true);//这是对上面两句的包装。
final View timepickerview = findViewById(R.id.timepicker);
wheelTime = new WheelTime(timepickerview, TimePickerType.Type.YEAR_MONTH_DAY);
if (!flag){
int endYear=a.getInt(R.styleable.TimePicker_endYear,2900);

wheelTime.setEndYear(endYear);
}


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

最近手上的项目要求弄一个包含两个日期选择控件的UI界面(即开始时间和结束时间)。

一、

一开始就想到使用自带的DatePicker控件。但是发现其UI很难调整到项目想要的效果。尤其是其与项目theme的关系,在xml中设置style也不好使。从Popwindow到AlertDialog都试过了,只有含单个DatePicker的DateAlertDialog还比较赏心悦目,却不满足项目需要。

于是决定用自定义DatePicker来实现。

通过一番波折,自己实现了大部分功能,但对日期的年月日的配合调整的不是很好。

无意间在网上发现了Pickerview这个开源项目。(地址:https://github.com/saiwu-bigkoo/Android-PickerView#demo-图片)其中的TimePickerView比较符合我的需求,就借来稍加改动,使用了起来。

二、

由于TimePickerView的不是传统意义上的控件,其使用方式比较固定,不方便。我稍加改动,创建了TimePicker控件。

该控件的功能是:提供年月日用于选择,可选范围是:1990年1月1日到当前时间。 通过getTime()可以获取用户选择的时间。

代码:

1、Timepicker.java

public class TimePicker extends LinearLayout {

WheelTime wheelTime;

private OnTimeSelectListener timeSelectListener;

public TimePicker(Context context) {
super(context);
}

public TimePicker(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater.from(context).inflate(R.layout.pickerview_time, this,true);//这是对上面两句的包装。
final View timepickerview = findViewById(R.id.timepicker);
wheelTime = new WheelTime(timepickerview, TimePickerType.Type.YEAR_MONTH_DAY);
//默认选中当前时间
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
int hours = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
wheelTime.setPicker(year, month, day, hours, minute);

this.setClickable(true);
this.setFocusable(true);
}
public Date getTime(){
String time= wheelTime.getTime();
Log.d("TimePicker","--------------getTime  "+time);
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
Date d=new Date();
try {
d=dateFormat.parse(time);
} catch (ParseException e) {
e.printStackTrace();
}
return d;
}

/**
* 设置可以选择的时间范围
* 要在setTime之前调用才有效果
* @param startYear 开始年份
* @param endYear 结束年份
*/
public void setRange(int startYear, int endYear) {
wheelTime.setStartYear(startYear);
wheelTime.setEndYear(endYear);
}

/**
* 设置选中时间
* @param date 时间
*/
public void setTime(Date date) {
Calendar calendar = Calendar.getInstance();
if (date == null)
calendar.setTimeInMillis(System.currentTimeMillis());
else
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);
int day = calendar.get(Calendar.DAY_OF_MONTH);
int hours = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
wheelTime.setPicker(year, month, day, hours, minute);
}

//    /**
//     * 指定选中的时间,显示选择器
//     *
//     * @param date
//     */
//    public void show(Date date) {
//        Calendar calendar = Calendar.getInstance();
//        if (date == null)
//            calendar.setTimeInMillis(System.currentTimeMillis());
//        else
//            calendar.setTime(date);
//        int year = calendar.get(Calendar.YEAR);
//        int month = calendar.get(Calendar.MONTH);
//        int day = calendar.get(Calendar.DAY_OF_MONTH);
//        int hours = calendar.get(Calendar.HOUR_OF_DAY);
//        int minute = calendar.get(Calendar.MINUTE);
//        wheelTime.setPicker(year, month, day, hours, minute);
//        show();
//    }

/**
* 设置是否循环滚动
* @param cyclic 是否循环
*/
public void setCyclic(boolean cyclic) {
wheelTime.setCyclic(cyclic);
}

}


2、对应布局文件pickerview_time.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">

<LinearLayout
android:id="@+id/timepicker"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:orientation="horizontal">

<com.koala.shop.mobile.teacher.widget.pickerview.lib.WheelView
android:id="@+id/year"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1" />

<com.koala.shop.mobile.teacher.widget.pickerview.lib.WheelView
android:id="@+id/month"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.1" />

<com.koala.shop.mobile.teacher.widget.pickerview.lib.WheelView
android:id="@+id/day"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.1" />

<com.koala.shop.mobile.teacher.widget.pickerview.lib.WheelView
android:id="@+id/hour"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.1" />

<com.koala.shop.mobile.teacher.widget.pickerview.lib.WheelView
android:id="@+id/min"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.1" />
</LinearLayout>

</LinearLayout>


3、Wheeltime.java

public class WheelTime {
public static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
private View view;
private WheelView wv_year;
private WheelView wv_month;
private WheelView wv_day;
private WheelView wv_hours;
private WheelView wv_mins;

private int year_now,month_now,day_now;

private TimePickerType.Type type;
public static final int DEFULT_START_YEAR = 1990;
public static final int DEFULT_END_YEAR = 2100;
private int startYear = DEFULT_START_YEAR;
private int endYear = DEFULT_END_YEAR;

public WheelTime(View view) {
super();
this.view = view;
type = TimePickerType.Type.ALL;
setView(view);
}

public WheelTime(View view, TimePickerType.Type type) {
super();
this.view = view;
this.type = type;
setView(view);
}

public void setPicker(int year, int month, int day) {
this.setPicker(year, month, day, 0, 0);
}

public void setPicker(int year, int month, int day, int h, int m) {
// 添加大小月月份并将其转换为list,方便之后的判断
String[] months_big = {"1", "3", "5", "7", "8", "10", "12"};
String[] months_little = {"4", "6", "9", "11"};

final List<String> list_big = Arrays.asList(months_big);
final List<String> list_little = Arrays.asList(months_little);

Context context = view.getContext();
// 年
wv_year = (WheelView) view.findViewById(R.id.year);
wv_year.setAdapter(new NumericWheelAdapter(startYear, endYear));// 设置"年"的显示数据
wv_year.setLabel(context.getString(R.string.pickerview_year));// 添加文字
Log.d("WheelTime","-----------------year  "+(year - startYear));
wv_year.setCurrentItem(year - startYear);// 初始化时显示的数据

// 月
wv_month = (WheelView) view.findViewById(R.id.month);
wv_month.setAdapter(new NumericWheelAdapter(1, month_now));
wv_month.setLabel(context.getString(R.string.pickerview_month));
Log.d("WheelTime","-----------------month  "+month);
wv_month.setCurrentItem(month);

// 日
wv_day = (WheelView) view.findViewById(R.id.day);
//        // 判断大小月及是否闰年,用来确定"日"的数据
//        if (list_big.contains(String.valueOf(month + 1))) {
//            wv_day.setAdapter(new NumericWheelAdapter(1, 31));
//        } else if (list_little.contains(String.valueOf(month + 1))) {
//            wv_day.setAdapter(new NumericWheelAdapter(1, 30));
//        } else {
//            // 闰年
//            if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
//                wv_day.setAdapter(new NumericWheelAdapter(1, 29));
//            else
//                wv_day.setAdapter(new NumericWheelAdapter(1, 28));
//        }
wv_day.setAdapter(new NumericWheelAdapter(1, day_now));
wv_day.setLabel(context.getString(R.string.pickerview_day));
Log.d("WheelTime","-----------------day  "+day);
wv_day.setCurrentItem(day - 1);

wv_hours = (WheelView) view.findViewById(R.id.hour);
wv_hours.setAdapter(new NumericWheelAdapter(0, 23));
wv_hours.setLabel(context.getString(R.string.pickerview_hours));// 添加文字
wv_hours.setCurrentItem(h);

wv_mins = (WheelView) view.findViewById(R.id.min);
wv_mins.setAdapter(new NumericWheelAdapter(0, 59));
wv_mins.setLabel(context.getString(R.string.pickerview_minutes));// 添加文字
wv_mins.setCurrentItem(m);

// 添加"年"监听
OnItemSelectedListener wheelListener_year = new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
int year_num = index + startYear;
// 判断大小月及是否闰年,用来确定"日"的数据
int maxItem = 30;
if (list_big
.contains(String.valueOf(wv_month.getCurrentItem() + 1))) {
wv_day.setAdapter(new NumericWheelAdapter(1, 31));
maxItem = 31;
} else if (list_little.contains(String.valueOf(wv_month
.getCurrentItem() + 1))) {
wv_day.setAdapter(new NumericWheelAdapter(1, 30));
maxItem = 30;
} else {
if ((year_num % 4 == 0 && year_num % 100 != 0)
|| year_num % 400 == 0) {
wv_day.setAdapter(new NumericWheelAdapter(1, 29));
maxItem = 29;
} else {
wv_day.setAdapter(new NumericWheelAdapter(1, 28));
maxItem = 28;
}
}
if (wv_day.getCurrentItem() > maxItem - 1) {
wv_day.setCurrentItem(maxItem - 1);
}
if (year_num==year_now){
//今年最大的月份只能是当前月
wv_month.setAdapter(new NumericWheelAdapter(1, month_now));

}else {
wv_month.setAdapter(new NumericWheelAdapter(1, 12));
}
}
};
// 添加"月"监听
OnItemSelectedListener wheelListener_month = new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
int month_num = index + 1;
int maxItem = 30;
// 判断大小月及是否闰年,用来确定"日"的数据
if (list_big.contains(String.valueOf(month_num))) {
wv_day.setAdapter(new NumericWheelAdapter(1, 31));
maxItem = 31;
} else if (list_little.contains(String.valueOf(month_num))) {
wv_day.setAdapter(new NumericWheelAdapter(1, 30));
maxItem = 30;
} else {
if (((wv_year.getCurrentItem() + startYear) % 4 == 0 && (wv_year
.getCurrentItem() + startYear) % 100 != 0)
|| (wv_year.getCurrentItem() + startYear) % 400 == 0) {
wv_day.setAdapter(new NumericWheelAdapter(1, 29));
maxItem = 29;
} else {
wv_day.setAdapter(new NumericWheelAdapter(1, 28));
maxItem = 28;
}
}
if (wv_day.getCurrentItem() > maxItem - 1) {
wv_day.setCurrentItem(maxItem - 1);
}
if (month_num==month_now){
//今年最大的月份只能是当前月
wv_day.setAdapter(new NumericWheelAdapter(1, day_now));
}
}
};
wv_year.setOnItemSelectedListener(wheelListener_year);
wv_month.setOnItemSelectedListener(wheelListener_month);

// 根据屏幕密度来指定选择器字体的大小(不同屏幕可能不同)
int textSize = 6;
switch (type) {
case ALL:
textSize = textSize * 3;
break;
case YEAR_MONTH_DAY:
textSize = textSize * 4;
wv_hours.setVisibility(View.GONE);
wv_mins.setVisibility(View.GONE);
break;
case HOURS_MINS:
textSize = textSize * 4;
wv_year.setVisibility(View.GONE);
wv_month.setVisibility(View.GONE);
wv_day.setVisibility(View.GONE);
break;
case MONTH_DAY_HOUR_MIN:
textSize = textSize * 3;
wv_year.setVisibility(View.GONE);
break;
case YEAR_MONTH:
textSize = textSize * 4;
wv_day.setVisibility(View.GONE);
wv_hours.setVisibility(View.GONE);
wv_mins.setVisibility(View.GONE);
}
wv_day.setTextSize(textSize);
wv_month.setTextSize(textSize);
wv_year.setTextSize(textSize);
wv_hours.setTextSize(textSize);
wv_mins.setTextSize(textSize);

}

/**
* 设置是否循环滚动
*
* @param cyclic
*/
public void setCyclic(boolean cyclic) {
wv_year.setCyclic(cyclic);
wv_month.setCyclic(cyclic);
wv_day.setCyclic(cyclic);
wv_hours.setCyclic(cyclic);
wv_mins.setCyclic(cyclic);
}

public String getTime() {
StringBuffer sb = new StringBuffer();
//        sb.append((wv_year.getCurrentItem() + startYear)).append("-")
//                .append((wv_month.getCurrentItem() + 1)).append("-")
//                .append((wv_day.getCurrentItem() + 1)).append(" ")
//                .append(wv_hours.getCurrentItem()).append(":")
//                .append(wv_mins.getCurrentItem());
sb.append((wv_year.getCurrentItem() + startYear)).append("-")
.append((wv_month.getCurrentItem() + 1)).append("-")
.append((wv_day.getCurrentItem() + 1));
return sb.toString();
}

public View getView() {
return view;
}

public void setView(View view) {
this.view = view;
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
year_now= calendar.get(Calendar.YEAR);
month_now = calendar.get(Calendar.MONTH)+1;
day_now = calendar.get(Calendar.DAY_OF_MONTH);
int hours = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
this.endYear=year_now;
}

public int getStartYear() {
return startYear;
}

public void setStartYear(int startYear) {
this.startYear = startYear;
}

public int getEndYear() {
return endYear;
}

public void setEndYear(int endYear) {
this.endYear = endYear;
}
}


提取出来的枚举类:

public class TimePickerType {
public enum Type {
ALL, YEAR_MONTH_DAY, HOURS_MINS, MONTH_DAY_HOUR_MIN , YEAR_MONTH
}// 四种选择模式,年月日时分,年月日,时分,月日时分
}


效果图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: