本文实例为大家分享了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 list;

// length

private int length;

/**

* Constructor

* @param items the items

* @param length the max items length

*/

public StringWheelAdapter(ArrayList 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 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();

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 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();

minuteList = new ArrayList();

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布局文件:

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical"

android:background="#FFF">

android:layout_width="match_parent"

android:layout_height="1dp"

android:background="#f5f5f5"/>

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal"

android:padding="10dp">

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" />

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" />

android:layout_width="match_parent"

android:layout_height="1dp"

android:background="#f5f5f5"/>

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal"

android:layout_marginTop="10dp"

android:padding="20dp">

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"/>

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"/>

主界面布局文件:

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="#FFF"

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

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical"

android:layout_alignParentBottom="true"

android:padding="10dp"

android:gravity="center">

android:layout_width="match_parent"

android:layout_height="1dp"

android:background="#f5f5f5"/>

android:id="@+id/btn_naozhong"

android:layout_width="30dp"

android:layout_height="30dp"

android:background="@drawable/naozhong"

/>

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实现自定义日期选择器

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

时间: 2018-07-24

android自定义滚动日期,Android基于wheelView实现自定义日期选择器相关推荐

  1. Android基于wheelView的自定义日期选择器(可拓展样式)

    基于wheelView的自定义日期选择器 项目要求效果图: 要求 "6月20 星期五" 这一项作为一个整体可以滑动,"7时"."48分"分别 ...

  2. android循环滚动textview,Android 循环上下滚动

    最近在做项目的时候遇到了一个上下滚动文字的需求,在网上找到了一个自定义的TextView,但是切换效果很图片,没有滚动的效果,考虑到html的marquee效果添加到TextView中,无奈没有效果, ...

  3. android 横向滚动图片,Android使用Photoview实现图片左右滑动及缩放功能

    Android使用Photoview实现图片左右滑动及缩放功能 发布时间:2020-10-12 14:51:12 来源:脚本之家 阅读:119 作者:kuaizilanqiu 我想,不管是做什么样的a ...

  4. android 文字滚动组件,Android textview 跑马灯文字滚动效果

    设置如下TextView控件文件的XML: android:id="@+id/textview" android:layout_width="match_parent&q ...

  5. Android横向滚动卡片,Android实现横向滑动卡片效果

    Android实现横向滑动卡片效果 发布时间:2020-09-04 22:51:17 来源:脚本之家 阅读:255 作者:itbobby 最近项目上需要实现这样效果的一个页面,本来想找个现成的两下搞定 ...

  6. android数字滚动动画,Android超简单实现金钱滚动效果

    目录 目录 效果展示 实现原理 利用ValueAnimator将数值从0一直增长到你所需要展示的数值,然后使用TextView将增长过程中的数值不断展示即可实现金钱的滚动效果. ValueAnimat ...

  7. Android横向滚动卡片,Android仿探探卡片式滑动效果实现

    前言 第一次进入探探软件界面,就被这种通过卡片式滑动来选择"喜欢/不喜欢"的设计所吸引了.当时就非常想通过自己来实现这种仿探探式的效果,然而却没什么思路.不过毋庸置疑的是,这种效果 ...

  8. android垂直滚动显示,Android 上下滚动字幕实现

    首先values文件夹下添加或创建attrs文件,如下: 1.自定义上下滚动字幕textview.VerticalRollingTextView /** * 作者:created by meixi * ...

  9. Android横向滚动卡片,Android滑动卡片成效:Swipecards

    一个类似于 Tinder的Android库,用于创建滑动卡片效果. 您可以向左或向右滑动来切换喜欢或不喜欢的内容. //implement the onFlingListener public cla ...

最新文章

  1. android id 重名_Android App 自定义权限重名不能安装解决办法
  2. CSDN湘苗培优|保持热情,告别平庸
  3. 迄今为止程序员写过的最大Bug:亏损30亿、致6人死亡,甚至差点毁灭世界
  4. Ubuntu Server 更改hostname
  5. Linux_RHEL7_LDAP、Autofs服务
  6. Android开发--AsyncTask异步任务(二)
  7. 盘点2021:数据中心行业迎来转折点
  8. 外部 Storage Provider - 每天5分钟玩转 Docker 容器技术(149)
  9. 创建一个最简单的imgui测试用例
  10. pythonrequest得替代_python的扩展包requests的高级用法
  11. ubuntu 绑定网卡
  12. iOS-推送通知详解
  13. php resize函数,Php Image Resize图片大小调整的函数代码
  14. MSP430初学two
  15. 人工智能数学基础9:集合相关概念
  16. 性能进阶:使用JMeter进行websocket测试【建议收藏】
  17. 苹果最早明年在Apple Watch中引入microLED显示屏
  18. 程序员写了个开源软件,完成了舔狗的绝地反杀...
  19. OpenCV fitline直线拟合函数学习
  20. Neutron DHCP-Agent问题分析定位(2)

热门文章

  1. 科研热点|2022诺贝尔奖各领域奖项已揭晓(附获奖者详细信息)~
  2. java 整数相除 小数点_java整数相除保留小数
  3. 一起去追寻那大漠孤烟
  4. buuctf-[GYCTF2020]Blacklist1(小宇特详解)
  5. 如何使用Arduino Uno开发板制作超声波测距仪
  6. 威胁快报|首爆,新披露Jenkins RCE漏洞成ImposterMiner挖矿木马新“跳板”
  7. Luogu P4168 [Violet]蒲公英(分块)
  8. 记一次Linux被入侵,服务器变“矿机”全过程
  9. 各大搜索引擎网站收录提交入口
  10. 解决报错【internal/modules/cjs/loader.js:905 throw err;】