Android基于wheelView实现自定义日期选择器

本文实例为大家分享了Android实现自定义日期选择器的具体代码,供大家参考,具体内容如下

项目要求效果图:

要求 “6月20 星期五” 这一项作为一个整体可以滑动,”7时”、”48分”分别作为一个滑动整体。

系统自带的DatePicker、TimePicker大家都知道,只有这种效果:

百度了很多,试了NumberPicker等都不行,本来打算自己写。网友推荐了一个开源组件WheelView,下下来试了试,发现他已经定义的很完善了,在他的基础上拓展很容易。

现将基于wheelView自定义日期选择器记录如下:

一.首先要了解WheelView为我们提供了什么:

这里写图片描述

除了我写的”DateObject”与”StringWheelAdapter”,其余都是WheelView提供的,

1. WheelView.java :可滚动的组件

主要方法:

setAdapter(new StringWheelAdapter(dateList, 7)); //设置Adapter

setVisibleItems(3); //设置显示几行数据

setCyclic(true); //设置是否循环显示数据

addChangingListener(onDaysChangedListener) //设置滑动监听器

2. WheelAdapter.java : 滑动组件的适配器的接口,子类适配器用于装载数据

public interface WheelAdapter {

/**

* Gets items count

* @return the count of wheel items

*/

public int getItemsCount();

/**

* Gets a wheel item by index.

*

* @param index the item index

* @return the wheel item text or null

*/

public String getItem(int index);

/**

* Gets maximum item length. It is used to determine the wheel width.

* If -1 is returned there will be used the default wheel width.

*

* @return the maximum item length or -1

*/

public int getMaximumLength();

}

3. OnWheelChangedListener.java : 滑动监听器接口

public interface OnWheelChangedListener {

/**

* Callback method to be invoked when current item changed

* @param wheel the wheel view whose state has changed

* @param oldValue the old value of current item

* @param newValue the new value of current item

*/

void onChanged(WheelView wheel, int oldValue, int newValue);

}

4.OnWheelScrollListener.java :滚动监听器接口(暂时没用到)

5.NumericWheelAdapter.java : 当滚动内容为纯数字时调用的适配器

6.DateObject.java : 日期实体类,用于存储、获取选择的数据

package kankan.wheel.widget;

import java.util.Calendar;

public class DateObject extends Object{

private int year ;

private int month;

private int day;

private int week;

private int hour;

private int minute;

private String listItem;

/**

* 日期对象的4个参数构造器,用于设置日期

* @param year

* @param month

* @param day

* @author sxzhang

*/

public DateObject(int year2, int month2, int day2,int week2) {

super();

this.year = year2;

int maxDayOfMonth = Calendar.getInstance().getActualMaximum(Calendar.DAY_OF_MONTH);

if(day2 > maxDayOfMonth){

this.month = month2 + 1;

this.day = day2 % maxDayOfMonth;

}else{

this.month = month2;

this.day = day2;

}

this.week = week2 % 7 == 0 ? 7 : week2 % 7;

if(day == Calendar.getInstance().get(Calendar.DAY_OF_MONTH)){

this.listItem = String.format("%02d", this.month) +"月" + String.format("%02d", this.day) +

"日 "+ " 今天 ";

}else{

this.listItem = String.format("%02d", this.month) +"月" + String.format("%02d", this.day) +

"日 "+ getDayOfWeekCN(week);

}

}

/**

* 日期对象的2个参数构造器,用于设置时间

* @param hour2

* @param minute2

* @param isHourType true:传入的是hour; false: 传入的是minute

* @author sxzhang

*/

public DateObject(int hour2,int minute2,boolean isHourType) {

super();

if(isHourType == true && hour2 != -1){ //设置小时

if(hour2 > 24){

this.hour = hour2 % 24;

}else

this.hour = hour2;

this.listItem = this.hour + "时";

}else if(isHourType == false && minute2 != -1){ //设置分钟

if(minute2 > 60)

this.minute = minute2 % 60;

else

this.minute = minute2;

this.listItem = this.minute + "分";

}

}

public int getHour() {

return hour;

}

public void setHour(int hour) {

this.hour = hour;

}

public int getMinute() {

return minute;

}

public void setMinute(int minute) {

this.minute = minute;

}

public int getWeek() {

return week;

}

public void setWeek(int week) {

this.week = week;

}

public int getYear() {

return year;

}

public void setYear(int year) {

this.year = year;

}

public int getMonth() {

return month;

}

public void setMonth(int month) {

this.month = month;

}

public int getDay() {

return day;

}

public void setDay(int day) {

this.day = day;

}

public String getListItem() {

return listItem;

}

public void setListItem(String listItem) {

this.listItem = listItem;

}

/**

* 根据day_of_week得到汉字星期

* @return

*/

public static String getDayOfWeekCN(int day_of_week){

String result = null;

switch(day_of_week){

case 1:

result = "星期日";

break;

case 2:

result = "星期一";

break;

case 3:

result = "星期二";

break;

case 4:

result = "星期三";

break;

case 5:

result = "星期四";

break;

case 6:

result = "星期五";

break;

case 7:

result = "星期六";

break;

default:

break;

}

return result;

}

}

7.StringWheelAdapter.java :一会儿将定义的滚动内容为字符串的适配器,当内容为字符串时我们就可以随意拓展滑动部分的内容

package kankan.wheel.widget;

import java.util.ArrayList;

/**

* The simple String Array wheel adapter

*

*/

public class StringWheelAdapter implements WheelAdapter {

/** The default items length */

public static final int DEFAULT_LENGTH = -1;

// items

private ArrayList<DateObject> list;

// length

private int length;

/**

* Constructor

* @param items the items

* @param length the max items length

*/

public StringWheelAdapter(ArrayList<DateObject> list, int length) {

this.list = list;

this.length = length;

}

@Override

public String getItem(int index) {

if (index >= 0 && index < list.size()) {

return list.get(index).getListItem();

}

return null;

}

@Override

public int getItemsCount() {

return list.size();

}

@Override

public int getMaximumLength() {

return length;

}

}

二.了解以后就可以使用他定义我们需要的了。

1.首先要做的是这个效果的部分:

这里写图片描述

我们将其命名为DatePicker:

package com.sxkeji.timeswitch.widget;

import java.util.ArrayList;

import java.util.Calendar;

import kankan.wheel.widget.DateObject;

import kankan.wheel.widget.OnWheelChangedListener;

import kankan.wheel.widget.StringWheelAdapter;

import kankan.wheel.widget.WheelView;

import android.content.Context;

import android.util.AttributeSet;

import android.widget.LinearLayout;

/**

* 自定义的日期选择器

* @author sxzhang

*

*/

public class DatePicker extends LinearLayout {

private Calendar calendar = Calendar.getInstance();

private WheelView newDays;

private ArrayList<DateObject> dateList ;

private OnChangeListener onChangeListener; //onChangeListener

private final int MARGIN_RIGHT = 20;

private DateObject dateObject; //日期数据对象

//Constructors

public DatePicker(Context context) {

super(context);

init(context);

}

public DatePicker(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}

/**

* 初始化

* @param context

*/

private void init(Context context){

int year = calendar.get(Calendar.YEAR);

int month = calendar.get(Calendar.MONTH) + 1;

int day = calendar.get(Calendar.DAY_OF_MONTH);

int week = calendar.get(Calendar.DAY_OF_WEEK);

dateList = new ArrayList<DateObject>();

for (int i = 0; i < 7; i++) {

dateObject = new DateObject(year, month, day+i, week+i);

dateList.add(dateObject);

}

newDays = new WheelView(context);

LayoutParams newDays_param = new LayoutParams(300,LayoutParams.WRAP_CONTENT);

newDays_param.setMargins(0, 0, MARGIN_RIGHT, 0);

newDays.setLayoutParams(newDays_param);

newDays.setAdapter(new StringWheelAdapter(dateList, 7));

newDays.setVisibleItems(3);

newDays.setCyclic(true);

newDays.addChangingListener(onDaysChangedListener);

addView(newDays);

}

/**

* 滑动改变监听器

*/

private OnWheelChangedListener onDaysChangedListener = new OnWheelChangedListener(){

@Override

public void onChanged(WheelView mins, int oldValue, int newValue) {

calendar.set(Calendar.DAY_OF_MONTH, newValue + 1);

change();

}

};

/**

* 滑动改变监听器回调的接口

*/

public interface OnChangeListener {

void onChange(int year, int month, int day, int day_of_week);

}

/**

* 设置滑动改变监听器

* @param onChangeListener

*/

public void setOnChangeListener(OnChangeListener onChangeListener){

this.onChangeListener = onChangeListener;

}

/**

* 滑动最终调用的方法

*/

private void change(){

if(onChangeListener!=null){

onChangeListener.onChange(

dateList.get(newDays.getCurrentItem()).getYear(),

dateList.get(newDays.getCurrentItem()).getMonth(),

dateList.get(newDays.getCurrentItem()).getDay(),

dateList.get(newDays.getCurrentItem()).getWeek());

}

}

/**

* 根据day_of_week得到汉字星期

* @return

*/

public static String getDayOfWeekCN(int day_of_week){

String result = null;

switch(day_of_week){

case 1:

result = "星期日";

break;

case 2:

result = "星期一";

break;

case 3:

result = "星期二";

break;

case 4:

result = "星期三";

break;

case 5:

result = "星期四";

break;

case 6:

result = "星期五";

break;

case 7:

result = "星期六";

break;

default:

break;

}

return result;

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

}

2.然后要做的是这个效果的部分

这里写图片描述

我们命名为TimePicker:

package com.sxkeji.timeswitch.widget;

import java.util.ArrayList;

import java.util.Calendar;

import kankan.wheel.widget.DateObject;

import kankan.wheel.widget.OnWheelChangedListener;

import kankan.wheel.widget.StringWheelAdapter;

import kankan.wheel.widget.WheelView;

import android.content.Context;

import android.util.AttributeSet;

import android.widget.LinearLayout;

/**

* 自定义的时间选择器

* @author sxzhang

*

*/

public class TimePicker extends LinearLayout{

private Calendar calendar = Calendar.getInstance();

private WheelView hours, mins; //Wheel picker

private OnChangeListener onChangeListener; //onChangeListener

private final int MARGIN_RIGHT = 15; //调整文字右端距离

private ArrayList<DateObject> hourList,minuteList;

private DateObject dateObject; //时间数据对象

//Constructors

public TimePicker(Context context) {

super(context);

init(context);

}

public TimePicker(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}

/**

* 初始化

* @param context

*/

private void init(Context context){

int hour = calendar.get(Calendar.HOUR_OF_DAY);

int minute = calendar.get(Calendar.MINUTE);

hourList = new ArrayList<DateObject>();

minuteList = new ArrayList<DateObject>();

for (int i = 0; i < 24; i++) {

dateObject = new DateObject(hour+i,-1,true);

hourList.add(dateObject);

}

for (int j = 0; j < 60; j++) {

dateObject = new DateObject(-1,minute+j,false);

minuteList.add(dateObject);

}

//小时选择器

hours = new WheelView(context);

LayoutParams lparams_hours = new LayoutParams(80,LayoutParams.WRAP_CONTENT);

lparams_hours.setMargins(0, 0, MARGIN_RIGHT, 0);

hours.setLayoutParams(lparams_hours);

hours.setAdapter(new StringWheelAdapter(hourList, 24));

hours.setVisibleItems(3);

hours.setCyclic(true);

hours.addChangingListener(onHoursChangedListener);

addView(hours);

//分钟选择器

mins = new WheelView(context);

mins.setLayoutParams(new LayoutParams(80,LayoutParams.WRAP_CONTENT));

mins.setAdapter(new StringWheelAdapter(minuteList,60));

mins.setVisibleItems(3);

mins.setCyclic(true);

mins.addChangingListener(onMinsChangedListener);

addView(mins);

}

//listeners

private OnWheelChangedListener onHoursChangedListener = new OnWheelChangedListener(){

@Override

public void onChanged(WheelView hours, int oldValue, int newValue) {

calendar.set(Calendar.HOUR_OF_DAY, newValue);

change();

}

};

private OnWheelChangedListener onMinsChangedListener = new OnWheelChangedListener(){

@Override

public void onChanged(WheelView mins, int oldValue, int newValue) {

calendar.set(Calendar.MINUTE, newValue);

change();

}

};

/**

* 滑动改变监听器回调的接口

*/

public interface OnChangeListener {

void onChange(int hour, int munite);

}

/**

* 设置滑动改变监听器

* @param onChangeListener

*/

public void setOnChangeListener(OnChangeListener onChangeListener){

this.onChangeListener = onChangeListener;

}

/**

* 滑动最终调用的方法

*/

private void change(){

if(onChangeListener!=null){

onChangeListener.onChange(getHourOfDay(), getMinute());

}

}

/**

* 获取小时

* @return

*/

public int getHourOfDay(){

return hourList.get(hours.getCurrentItem()).getHour();

}

/**

* 获取分钟

* @return

*/

public int getMinute(){

return minuteList.get(mins.getCurrentItem()).getMinute();

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

}

}

3.最后就可以直接使用了,我这里主界面是一个button,点击后弹出popupWindow显示日期选择器。布局文件及主Activity如下:

popupWindow布局文件:

<?xml version="1.0" encoding="utf-8"?>

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

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical"

android:background="#FFF">

<View

android:layout_width="match_parent"

android:layout_height="1dp"

android:background="#f5f5f5"/>

<RelativeLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal"

android:padding="10dp">

<TextView

android:id="@+id/tv_cancel"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="取消"

android:layout_marginLeft="10dp"

android:layout_alignParentLeft="true"

android:textColor="#000000"

android:textSize="20sp" />

<TextView

android:id="@+id/tv_ok"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="确定"

android:layout_marginRight="10dp"

android:layout_alignParentRight="true"

android:textColor="#000000"

android:textSize="20sp" />

</RelativeLayout>

<View

android:layout_width="match_parent"

android:layout_height="1dp"

android:background="#f5f5f5"/>

<LinearLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal"

android:layout_marginTop="10dp"

android:padding="20dp">

<com.sxkeji.timeswitch.widget.DatePicker

android:id="@+id/dp_test"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="3"

android:gravity="center"

android:layout_gravity="center_horizontal"/>

<com.sxkeji.timeswitch.widget.TimePicker

android:id="@+id/tp_test"

android:layout_width="0dp"

android:layout_height="wrap_content"

android:layout_weight="2"

android:gravity="center"

android:layout_gravity="center_horizontal"/>

</LinearLayout>

</LinearLayout>

主界面布局文件:

<?xml version="1.0" encoding="utf-8"?>

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

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#FFF"

android:id="@+id/Rl_all">

<LinearLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical"

android:layout_alignParentBottom="true"

android:padding="10dp"

android:gravity="center">

<View

android:layout_width="match_parent"

android:layout_height="1dp"

android:background="#f5f5f5"/>

<Button

android:id="@+id/btn_naozhong"

android:layout_width="30dp"

android:layout_height="30dp"

android:background="@drawable/naozhong"

/>

</LinearLayout>

</RelativeLayout>

Activity代码:

package com.sxkeji.timeswitch.activity;

import java.util.Calendar;

import org.unism.wang.R;

import com.sxkeji.timeswitch.widget.DatePicker;

import com.sxkeji.timeswitch.widget.TimePicker;

import android.app.Activity;

import android.os.Bundle;

import android.view.Gravity;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.LinearLayout;

import android.widget.PopupWindow;

import android.widget.RelativeLayout;

import android.widget.TextView;

import android.widget.Toast;

/**

* 主页面

* @author sxzhang

*/

public class MyPickerActivity extends Activity {

private Calendar calendar;

private DatePicker dp_test;

private TimePicker tp_test;

private TextView tv_ok,tv_cancel; //确定、取消button

private Button btn_naozhong;

private PopupWindow pw;

private String selectDate,selectTime;

//选择时间与当前时间,用于判断用户选择的是否是以前的时间

private int currentHour,currentMinute,currentDay,selectHour,selectMinute,selectDay;

//整体布局

private RelativeLayout Rl_all;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

Rl_all = (RelativeLayout) findViewById(R.id.Rl_all);

btn_naozhong = (Button) findViewById(R.id.btn_naozhong);

calendar = Calendar.getInstance();

btn_naozhong.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View arg0) {

View view = View.inflate(MyPickerActivity.this, R.layout.dialog_select_time, null);

selectDate = calendar.get(Calendar.YEAR) + "年" + calendar.get(Calendar.MONTH) + "月"

+ calendar.get(Calendar.DAY_OF_MONTH) + "日"

+ DatePicker.getDayOfWeekCN(calendar.get(Calendar.DAY_OF_WEEK));

//选择时间与当前时间的初始化,用于判断用户选择的是否是以前的时间,如果是,弹出toss提示不能选择过去的时间

selectDay = currentDay = calendar.get(Calendar.DAY_OF_MONTH);

selectMinute = currentMinute = calendar.get(Calendar.MINUTE);

selectHour = currentHour = calendar.get(Calendar.HOUR_OF_DAY);

selectTime = currentHour + "点" + ((currentMinute < 10)?("0"+currentMinute):currentMinute) + "分";

dp_test = (DatePicker)view.findViewById(R.id.dp_test);

tp_test = (TimePicker)view.findViewById(R.id.tp_test);

tv_ok = (TextView) view.findViewById(R.id.tv_ok);

tv_cancel = (TextView) view.findViewById(R.id.tv_cancel);

//设置滑动改变监听器

dp_test.setOnChangeListener(dp_onchanghelistener);

tp_test.setOnChangeListener(tp_onchanghelistener);

pw = new PopupWindow(view, LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT, true);

// //设置这2个使得点击pop以外区域可以去除pop

// pw.setOutsideTouchable(true);

// pw.setBackgroundDrawable(new BitmapDrawable());

//出现在布局底端

pw.showAtLocation(Rl_all, 0, 0, Gravity.END);

//点击确定

tv_ok.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View arg0) {

if(selectDay == currentDay ){ //在当前日期情况下可能出现选中过去时间的情况

if(selectHour < currentHour){

Toast.makeText(getApplicationContext(), "不能选择过去的时间\n 请重新选择", 0).show();

}else if( (selectHour == currentHour) && (selectMinute < currentMinute) ){

Toast.makeText(getApplicationContext(), "不能选择过去的时间\n 请重新选择", 0).show();

}else{

Toast.makeText(getApplicationContext(), selectDate+selectTime, 0).show();

pw.dismiss();

}

}else{

Toast.makeText(getApplicationContext(), selectDate+selectTime, 0).show();

pw.dismiss();

}

}

});

//点击取消

tv_cancel.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View arg0) {

pw.dismiss();

}

});

}

});

}

//listeners

DatePicker.OnChangeListener dp_onchanghelistener = new DatePicker.OnChangeListener() {

@Override

public void onChange(int year, int month, int day, int day_of_week) {

selectDay = day;

selectDate = year + "年" + month + "月" + day + "日" + DatePicker.getDayOfWeekCN(day_of_week);

}

};

TimePicker.OnChangeListener tp_onchanghelistener = new TimePicker.OnChangeListener() {

@Override

public void onChange(int hour, int minute) {

selectTime = hour + "点" + ((minute < 10)?("0"+minute):minute) + "分";

selectHour = hour;

selectMinute = minute;

}

};

}

最终效果图:

源码下载:Android实现自定义日期选择器

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 Android基于wheelView实现自定义日期选择器 的全部内容, 来源链接: utcz.com/p/240890.html

回到顶部