首页 > 系统 > Android > 正文

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

2019-10-21 21:45:38
字体:
来源:转载
供稿:网友

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

项目要求效果图:

Android,wheelView,日期选择器

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

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

Android,wheelView,日期选择器

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

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

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

Android,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.首先要做的是这个效果的部分:

Android,wheelView,日期选择器

我们将其命名为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.然后要做的是这个效果的部分

Android,wheelView,日期选择器

我们命名为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,wheelView,日期选择器

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

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


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表