您的位置:首页 > 其它

自定义Dialog实现日期选择器

2017-03-29 09:35 567 查看
自定义Dialog实现日期选择器

1.用WheelView实现

老规矩,先看看实现的效果:








1. 先自定义View写一个WheelView:



package com.example.administrator.myapplication;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader.TileMode;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;

/**
* ClassName:WheelView
* Author:JiangPing
* Fuction:WheelView滚轮
* CreateDate:
* UpdateAuthor:
* UpdateDate:
*/
public class WheelView extends View {

/**
*

Attributes
attr 属性	description 描述
lineColor	divider line color 分割线颜色
lineHeight	divider line height 分割线高度
itemNumber	wheelview show item count 此wheelView显示item的个数
maskHight	mask height 蒙版高度(normalText的位置)
noEmpty	if set true select area can't be null(empty),or could be empty 设置true则选中不能为空,否则可以是空
normalTextColor	unSelected Text color 未选中文本颜色
normalTextSize	unSelected Text size 未选中文本字体大小
selectedTextColor	selected Text color 选中文本颜色
selectedTextSize	selected Text size 选中文本字体大小
unitHight	item unit height 每个item单元的高度

Method
1. setData(ArrayList data)

set WheelView data
设置WheelView的数据

2. resetData(ArrayList data)

reset WheelView data ,if you has setData
重置 WheelView的数据,如果已经设置过的话

3. int getSelected()

get selected item index
获取选中项的index

4. String getSelectedText()

get selected item text
获取选中项的文本信息

5. boolean isScrolling

is WheelView is scrolling
获取WheelView是否在滚动中

6. boolean isEnable()

is WheelView is enable
获取wheelView是否可用

7. void setEnable(boolean isEnable)

set WheelView enable
设置WheelView是否可用

8. void setDefault(int index)

set default selected index
设置默认选中项的index

9. int getListSize()

get WheelView item count
获取WheelView的item项个数

10. String getItemText(int index)

get the text by index
获取index位置上的文本数据

11. void setOnSelectListener(OnSelectListener onSelectListener)

set listener on WheelView that can get info when WheelView is scrolling or stop scroll.
对WheelView设置监听,在 滑动过程 或者 滑动停止 返回数据信息。
*/

/**
* 控件宽度
*/
private float controlWidth;
/**
* 控件高度
*/
private float controlHeight;
/**
* 是否滑动中
*/
private boolean isScrolling = false;
/**
* 选择的内容
*/
private ArrayList itemList = new ArrayList<>();
/**
* 设置数据
*/
private ArrayList dataList = new ArrayList<>();
/**
* 按下的坐标
*/
private int downY;
/**
* 按下的时间
*/
private long downTime = 0;
/**
* 短促移动
*/
private long goonTime = 200;
/**
* 短促移动距离
*/
private int goonDistence = 100;
/**
* 画线画笔
*/
private Paint linePaint;
/**
* 线的默认颜色
*/
private int lineColor = 0xff000000;
/**
* 线的默认宽度
*/
private float lineWidth = 2f;
/**
* 默认字体
*/
private float normalFont = 14.0f;
/**
* 选中的时候字体
*/
private float selectedFont = 22.0f;
/**
* 单元格高度
*/
private int unitHeight = 50;
/**
* 显示多少个内容
*/
private int itemNumber = 7;
/**
* 默认字体颜色
*/
private int normalColor = 0xff000000;
/**
* 选中时候的字体颜色
*/
private int selectedColor = 0xffff0000;
/**
* 蒙板高度
*/
private float maskHight = 48.0f;
/**
* 选择监听
*/
private OnSelectListener onSelectListener;
/**
* 是否可用
*/
private boolean isEnable = true;
/**
* 刷新界面
*/
private static final int REFRESH_VIEW = 0x001;
/**
* 移动距离
*/
private static final int MOVE_NUMBER = 5;
/**
* 是否允许选空
*/
private boolean noEmpty = true;

/**
* 正在修改数据,避免ConcurrentModificationException异常
*/
private boolean isClearing = false;

public WheelView(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
initData();
}

public WheelView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
initData();
}

public WheelView(Context context) {
super(context);
initData();
}

@Override
public boolean onTouchEvent(MotionEvent event) {

if (!isEnable)
return true;
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
isScrolling = true;
downY = (int) event.getY();
downTime = System.currentTimeMillis();
break;
case MotionEvent.ACTION_MOVE:
actionMove(y - downY);
onSelectListener();
break;
case MotionEvent.ACTION_UP:
int move = Math.abs(y - downY);
// 判断段时间移动的距离
if (System.currentTimeMillis() - downTime < goonTime
&& move > goonDistence) {
goonMove(y - downY);
} else {
actionUp(y - downY);
}
noEmpty();
isScrolling = false;
break;
default:
break;
}
return true;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

drawLine(canvas);
drawList(canvas);
drawMask(canvas);
}

private synchronized void drawList(Canvas canvas) {
if (isClearing)
return;
try {
for (ItemObject itemObject : itemList) {
itemObject.drawSelf(canvas);
}
} catch (Exception e) {
}

}

@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
super.onLayout(changed, left, top, right, bottom);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
controlWidth = getWidth();
if (controlWidth != 0) {
setMeasuredDimension(getWidth(), itemNumber * unitHeight);
controlWidth = getWidth();
}

}

/**
* 继续移动一定距离
*/
private synchronized void goonMove(final int move) {
new Thread(new Runnable() {

@Override
public void run() {
int distence = 0;
while (distence < unitHeight * MOVE_NUMBER) {
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
actionThreadMove(move > 0 ? distence : distence * (-1));
distence += 10;

}
actionUp(move > 0 ? distence - 10 : distence * (-1) + 10);
noEmpty();
}
}).start();
}

/**
* 不能为空,必须有选项
*/
private void noEmpty() {
if (!noEmpty)
return;
for (ItemObject item : itemList) {
if (item.isSelected())
return;
}
int move = (int) itemList.get(0).moveToSelected();
if (move < 0) {
defaultMove(move);
} else {
defaultMove((int) itemList.get(itemList.size() - 1)
.moveToSelected());
}
for (ItemObject item : itemList) {
if (item.isSelected()) {
if (onSelectListener != null)
onSelectListener.endSelect(this, item.id, item.itemText);
break;
}
}
}

/**
* 初始化数据
*/
private void initData() {
isClearing = t
1d91c
rue;
itemList.clear();
for (int i = 0; i < dataList.size(); i++) {
ItemObject itmItemObject = new ItemObject();
itmItemObject.id = i;
itmItemObject.itemText = dataList.get(i);
itmItemObject.x = 0;
itmItemObject.y = i * unitHeight;
itemList.add(itmItemObject);
}
isClearing = false;
}

/**
* 移动的时候
*
* @param move
*/
private void actionMove(int move) {
for (ItemObject item : itemList) {
item.move(move);
}
invalidate();
}

/**
* 移动,线程中调用
*
* @param move
*/
private void actionThreadMove(int move) {
for (ItemObject item : itemList) {
item.move(move);
}
Message rMessage = new Message();
rMessage.what = REFRESH_VIEW;
handler.sendMessage(rMessage);
}

/**
* 松开的时候
*
* @param move
*/
private void actionUp(int move) {
int newMove = 0;
if (move > 0) {
for (int i = 0; i < itemList.size(); i++) {
if (itemList.get(i).isSelected()) {
newMove = (int) itemList.get(i).moveToSelected();
if (onSelectListener != null)
onSelectListener.endSelect(this, itemList.get(i).id,
itemList.get(i).itemText);
break;
}
}
} else {
for (int i = itemList.size() - 1; i >= 0; i--) {
if (itemList.get(i).isSelected()) {
newMove = (int) itemList.get(i).moveToSelected();
if (onSelectListener != null)
onSelectListener.endSelect(WheelView.this, itemList.get(i).id,
itemList.get(i).itemText);
break;
}
}
}
for (ItemObject item : itemList) {
item.newY(move + 0);
}
slowMove(newMove);
Message rMessage = new Message();
rMessage.what = REFRESH_VIEW;
handler.sendMessage(rMessage);

}

/**
* 缓慢移动
*
* @param move
*/
private synchronized void slowMove(final int move) {
new Thread(new Runnable() {

@Override
public void run() {
// 判断政府
int m = move > 0 ? move : move * (-1);
int i = move > 0 ? 1 : (-1);
// 移动速度
int speed = 1;
while (true) {
m = m - speed;
if (m <= 0) {
for (ItemObject item : itemList) {
item.newY(m * i);
}
Message rMessage = new Message();
rMessage.what = REFRESH_VIEW;
handler.sendMessage(rMessage);
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
}
for (ItemObject item : itemList) {
item.newY(speed * i);
}
Message rMessage = new Message();
rMessage.what = REFRESH_VIEW;
handler.sendMessage(rMessage);
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (ItemObject item : itemList) {
if (item.isSelected()) {
if (onSelectListener != null)
onSelectListener.endSelect(WheelView.this, item.id, item.itemText);
break;
}
}

}
}).start();
}

/**
* 移动到默认位置
*
* @param move
*/
private void defaultMove(int move) {
for (ItemObject item : itemList) {
item.newY(move);
}
Message rMessage = new Message();
rMessage.what = REFRESH_VIEW;
handler.sendMessage(rMessage);
}

/**
* 滑动监听
*/
private void onSelectListener() {
if (onSelectListener == null)
return;
for (ItemObject item : itemList) {
if (item.isSelected()) {
onSelectListener.selecting(WheelView.this, item.id, item.itemText);
}
}
}

/**
* 绘制线条
*
* @param canvas
*/
private void drawLine(Canvas canvas) {

if (linePaint == null) {
linePaint = new Paint();
linePaint.setColor(lineColor);
linePaint.setAntiAlias(true);
linePaint.setStrokeWidth(lineWidth);
}

canvas.drawLine(0, controlHeight / 2 - unitHeight / 2 + 2,
controlWidth, controlHeight / 2 - unitHeight / 2 + 2, linePaint);
canvas.drawLine(0, controlHeight / 2 + unitHeight / 2 - 2,
controlWidth, controlHeight / 2 + unitHeight / 2 - 2, linePaint);
}

/**
* 绘制遮盖板
*
* @param canvas
*/
private void drawMask(Canvas canvas) {
LinearGradient lg = new LinearGradient(0, 0, 0, maskHight, 0x00f2f2f2,
0x00f2f2f2, TileMode.MIRROR);
Paint paint = new Paint();
paint.setShader(lg);
canvas.drawRect(0, 0, controlWidth, maskHight, paint);

LinearGradient lg2 = new LinearGradient(0, controlHeight - maskHight,
0, controlHeight, 0x00f2f2f2, 0x00f2f2f2, TileMode.MIRROR);
Paint paint2 = new Paint();
paint2.setShader(lg2);
canvas.drawRect(0, controlHeight - maskHight, controlWidth,
controlHeight, paint2);
}

/**
* 初始化,获取设置的属性
*
* @param context
* @param attrs
*/
private void init(Context context, AttributeSet attrs) {

TypedArray attribute = context.obtainStyledAttributes(attrs,
R.styleable.WheelView);
unitHeight = (int) attribute.getDimension(
R.styleable.WheelView_unitHight, 32);
normalFont = attribute.getDimension(
R.styleable.WheelView_normalTextSize, 14.0f);
selectedFont = attribute.getDimension(
R.styleable.WheelView_selectedTextSize, 22.0f);
itemNumber = attribute.getInt(R.styleable.WheelView_itemNumber, 7);
normalColor = attribute.getColor(
R.styleable.WheelView_normalTextColor, 0xff000000);
selectedColor = attribute.getColor(
R.styleable.WheelView_selectedTextColor, 0xffff0000);
lineColor = attribute.getColor(R.styleable.WheelView_lineColor,
0xff000000);
lineWidth = attribute.getDimension(R.styleable.WheelView_lineHeight, 2f);
maskHight = attribute.getDimension(R.styleable.WheelView_maskHight,
48.0f);
noEmpty = attribute.getBoolean(R.styleable.WheelView_noEmpty, true);
isEnable = attribute
.getBoolean(R.styleable.WheelView_isEnable, true);
attribute.recycle();

controlHeight = itemNumber * unitHeight;

}

/**
* 设置数据 (第一次)
*
* @param data
*/
public void setData(ArrayList data) {
this.dataList = data;
initData();
}

/**
* 重置数据
*
* @param data
*/
public void resetData(ArrayList data) {
setData(data);
invalidate();
}

/**
* 获取返回项 id
*
* @return
*/
public int getSelected() {
for (ItemObject item : itemList) {
if (item.isSelected())
return item.id;
}
return -1;
}

/**
* 获取返回的内容
*
* @return
*/
public String getSelectedText() {
for (ItemObject item : itemList) {
if (item.isSelected())
return item.itemText;
}
return "";
}

/**
* 是否正在滑动
*
* @return
*/
public boolean isScrolling() {
return isScrolling;
}

/**
* 是否可用
*
* @return
*/
public boolean isEnable() {
return isEnable;
}

/**
* 设置是否可用
*
* @param isEnable
*/
public void setEnable(boolean isEnable) {
this.isEnable = isEnable;
}

/**
* 设置默认选项
*
* @param index
*/
public void setDefault(int index) {
if (index > itemList.size() - 1)
return;
float move = itemList.get(index).moveToSelected();
defaultMove((int) move);
}

/**
* 获取列表大小
*
* @return
*/
public int getListSize() {
if (itemList == null)
return 0;
return itemList.size();
}

/**
* 获取某项的内容
*
* @param index
* @return
*/
public String getItemText(int index) {
if (itemList == null)
return "";
return itemList.get(index).itemText;
}

/**
* 监听
*
* @param onSelectListener
*/
public void setOnSelectListener(OnSelectListener onSelectListener) {
this.onSelectListener = onSelectListener;
}

@SuppressLint("HandlerLeak")
Handler handler = new Handler() {

@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case REFRESH_VIEW:
invalidate();
break;
default:
break;
}
}

};

/**
* 单条内容
*
* @author JiangPing
*/
private class ItemObject {
/**
* id
*/
public int id = 0;
/**
* 内容
*/
public String itemText = "";
/**
* x坐标
*/
public int x = 0;
/**
* y坐标
*/
public int y = 0;
/**
* 移动距离
*/
public int move = 0;
/**
* 字体画笔
*/
private Paint textPaint;
/**
* 字体范围矩形
*/
private Rect textRect;

public ItemObject() {
super();
}

/**
* 绘制自身
*
* @param canvas
*/
public void drawSelf(Canvas canvas) {

if (textPaint == null) {
textPaint = new Paint();
textPaint.setAntiAlias(true);
}

if (textRect == null)
textRect = new Rect();

// 判断是否被选择
if (isSelected()) {
textPaint.setColor(selectedColor);
// 获取距离标准位置的距离
float moveToSelect = moveToSelected();
moveToSelect = moveToSelect > 0 ? moveToSelect : moveToSelect
* (-1);
// 计算当前字体大小
float textSize = (float) normalFont
+ ((float) (selectedFont - normalFont) * (1.0f - (float) moveToSelect
/ (float) unitHeight));
textPaint.setTextSize(textSize);
} else {
textPaint.setColor(normalColor);
textPaint.setTextSize(normalFont);
}

// 返回包围整个字符串的最小的一个Rect区域
textPaint.getTextBounds(itemText, 0, itemText.length(), textRect);
// 判断是否可视
if (!isInView())
return;

// 绘制内容
canvas.drawText(itemText, x + controlWidth / 2 - textRect.width()
/ 2, y + move + unitHeight / 2 + textRect.height() / 2,
textPaint);

}

/**
* 是否在可视界面内
*
* @return
*/
public boolean isInView() {
if (y + move > controlHeight
|| (y + move + unitHeight / 2 + textRect.height() / 2) < 0)
return false;
return true;
}

/**
* 移动距离
*
* @param _move
*/
public void move(int _move) {
this.move = _move;
}

/**
* 设置新的坐标
*
* @param _move
*/
public void newY(int _move) {
this.move = 0;
this.y = y + _move;
}

/**
* 判断是否在选择区域内
*
* @return
*/
public boolean isSelected() {
if ((y + move) >= controlHeight / 2 - unitHeight / 2 + 2
&& (y + move) <= controlHeight / 2 + unitHeight / 2 - 2)
return true;
if ((y + move + unitHeight) >= controlHeight / 2 - unitHeight / 2
+ 2
&& (y + move + unitHeight) <= controlHeight / 2
+ unitHeight / 2 - 2)
return true;
if ((y + move) <= controlHeight / 2 - unitHeight / 2 + 2
&& (y + move + unitHeight) >= controlHeight / 2
+ unitHeight / 2 - 2)
return true;
return false;
}

/**
* 获取移动到标准位置需要的距离
*/
public float moveToSelected() {
return (controlHeight / 2 - unitHeight / 2) - (y + move);
}
}

/**
* 选择监听
*
* @author JiangPing
*/
public interface OnSelectListener {
/**
* 结束选择
*
* @param id
* @param text
*/
public void endSelect(View view, int id, String text);

/**
* 选中的内容
*
* @param id
* @param text
*/
public void selecting(View view, int id, String text);

}
}


2. 自定义一个Dialog,嵌套三个WheelView来实现年月日的选择。Dialog刚打开时显示的是当前日期:

package com.example.administrator.myapplication;

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;

/**
* Created by Administrator on 2017/3/8.
*/
public class DateDialog extends Dialog implements WheelView.OnSelectListener{

private TextView tv_date_cancel, tv_date_sure;
private onNoOnclickListener noOnclickListener;//取消按钮被点击了的监听器
private onYesOnclickListener yesOnclickListener;//确定按钮被点击了的监听器
Context mContext;
TextView tv_title;
String title,date;
CallBackListener mCallBackListener;

/**
* 获取选择的年
*
* @return
*/
public String getYear() {
Log.d("TAG", mWheelYear.getSelectedText());
return mWheelYear.getSelectedText();
}

/**
* 获取选择的月
*
* @return
*/
public String getMonth() {
Log.d("TAG", mWheelMonth.getSelectedText());
return mWheelMonth.getSelectedText();
}

/**
* 获取选择的日
*
* @return
*/
public String getDay() {
Log.d("TAG", mWheelDay.getSelectedText());
return mWheelDay.getSelectedText();
}

public String getDate() {
Log.d("TAG", mWheelYear.getSelectedText() + "-" + mWheelMonth.getSelectedText() + "-" + mWheelDay.getSelectedText());
date = mWheelYear.getSelectedText() + "-" + mWheelMonth.getSelectedText() + "-" + mWheelDay.getSelectedText();
return date;
}

private WheelView mWheelYear;
private WheelView mWheelMonth;
private WheelView mWheelDay;

public DateDialog(Context context, String str) {
super(context);
mContext = context;
title = str;
}

public DateDialog(Context context, int themeResId) {
super(context, R.style.MyDialog);
}

/**
* 设置取消按钮的显示内容和监听
*
* @param onNoOnclickListener
*/
public void setNoOnclickListener(onNoOnclickListener onNoOnclickListener) {

this.noOnclickListener = onNoOnclickListener;
}

/**
* 设置确定按钮的显示内容和监听
*
* @param onYesOnclickListener
*/
public void setYesOnclickListener(onYesOnclickListener onYesOnclickListener) {
this.yesOnclickListener = onYesOnclickListener;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.datepicker_layout);
//按空白处不能取消动画
setCanceledOnTouchOutside(false);
//初始化界面控件
setupViews();
//操作事件
initEvent();
}

private void initEvent() {
tv_date_cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (noOnclickListener != null) {
noOnclickListener.onNoClick();
}
}
});
tv_date_sure.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (yesOnclickListener != null) {
yesOnclickListener.onYesClick();
mCallBackListener.getDate(date);
}
}
});
}

private void setupViews() {
tv_date_cancel = (TextView) findViewById(R.id.tv_date_cancel);
tv_date_sure = (TextView) findViewById(R.id.tv_date_sure);
tv_title = (TextView) findViewById(R.id.tv_title);
tv_title.setText(title);

mWheelYear = (WheelView) findViewById(R.id.wv_year);
mWheelMonth = (WheelView) findViewById(R.id.wv_month);
mWheelDay = (WheelView) findViewById(R.id.wv_day);

// 格式化当前时间,并转换为年月日整型数据
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
String[] split = sdf.format(new Date()).split("-");
int currentYear = Integer.parseInt(split[0]);
int currentMonth = Integer.parseInt(split[1]);
int currentDay = Integer.parseInt(split[2]);

// 设置默认年月日为当前日期
mWheelYear.setData(getYearData(currentYear));
mWheelYear.setDefault(0);
mWheelMonth.setData(getMonthData());
mWheelMonth.setDefault(currentMonth - 1);
mWheelDay.setData(getDayData(getLastDay(currentYear, currentMonth)));
mWheelDay.setDefault(currentDay - 1);

mWheelYear.setOnSelectListener(this);
mWheelMonth.setOnSelectListener(this);
mWheelDay.setOnSelectListener(this);
}

/**
* 年范围在:1900~今年
*
* @param currentYear
* @return
*/
private ArrayList getYearData(int currentYear) {
ArrayList list = new ArrayList<>();
for (int i = currentYear; i >= 1900; i--) {
list.add(String.valueOf(i));
}
return list;
}

private ArrayList getMonthData() {
ArrayList list = new ArrayList<>();
for (int i = 1; i <= 12; i++) {
list.add(String.valueOf(i));
}
return list;
}

/**
* 日范围在1~lastDay
*
* @param lastDay
* @return
*/
private ArrayList getDayData(int lastDay) {
//ignore condition
ArrayList list = new ArrayList<>();
for (int i = 1; i <= lastDay; i++) {
list.add(String.valueOf(i));
}
return list;
}

/**
* 判断是否闰年
*
* @param year
* @return
*/
private boolean isLeapYear(int year) {
return (year % 100 == 0 && year % 400 == 0) || (year % 100 != 0 && year % 4 == 0);
}

/**
* 获取特定年月对应的天数
*
* @param year
* @param month
* @return
*/
private int getLastDay(int year, int month) {
if (month == 2) {
// 2月闰年的话返回29,防止28
return isLeapYear(year) ? 29 : 28;
}
// 一三五七八十腊,三十一天永不差
return month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 ? 31 : 30;
}

@Override
public void endSelect(View view, int id, String text) {
// 滚轮滑动停止后调用
switch (view.getId()) {
case R.id.wv_year:{
getYear();
}
case R.id.wv_month: {
getMonth();
// 记录当前选择的天数
int selectDay = Integer.parseInt(getDay());
// 根据当前选择的年月获取对应的天数
int lastDay = getLastDay(Integer.parseInt(getYear()), Integer.parseInt(getMonth()));
// 设置天数
mWheelDay.setData(getDayData(lastDay));
// 如果选中的天数大于实际天数,那么将默认天数设为实际天数;否则还是设置默认天数为选中的天数
if (selectDay > lastDay) {
mWheelDay.setDefault(lastDay - 1);
} else {
mWheelDay.setDefault(selectDay - 1);
}
}
case R.id.wv_day: {
getDay();
}
getDate();
}
}

@Override
public void selecting(View view, int id, String text) {

}

/**
* 设置确定按钮和取消被点击的接口
*/
public interface onYesOnclickListener {
public void onYesClick();
}

public interface onNoOnclickListener {
public void onNoClick();
}

//接口回调,返回日期数据
public interface CallBackListener {
public void getDate(String date);
}

public void setCallBackListener(CallBackListener mCallBackListener){
this.mCallBackListener = mCallBackListener;
}
}


3. MainActivity的代码实现:


package com.example.administrator.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.PopupWindow;
import android.widget.TextView;

import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity extends AppCompatActivity {

TextView tv_start_date, tv_end_date;
DateDialog dateDialog;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化控件
setupViews();
//设置监听事件
initEvent();
}

private void initEvent() {
final String[] title = {"选择初始时间", "选择结束时间"};
tv_start_date.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dateDialog = new DateDialog(MainActivity.this, title[0]);
dateDialog.show();
dateDialog.setYesOnclickListener(new DateDialog.onYesOnclickListener() {
@Override
public void onYesClick() {
dateDialog.setCallBackListener(new DateDialog.CallBackListener() {
@Override
public void getDate(String date) {
if (date == null) {
tv_start_date.setText(getDefautDate());
} else {
tv_start_date.setText(date);
}
}
});
dateDialog.dismiss();
}
});
dateDialog.setNoOnclickListener(new DateDialog.onNoOnclickListener() {
@Override
public void onNoClick() {
dateDialog.dismiss();
}
});
}
});

tv_end_date.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dateDialog = new DateDialog(MainActivity.this, title[1]);
dateDialog.show();
dateDialog.setYesOnclickListener(new DateDialog.onYesOnclickListener() {
@Override
public void onYesClick() {
dateDialog.setCallBackListener(new DateDialog.CallBackListener() {
@Override
public void getDate(String date) {
if (date == null) {
tv_end_date.setText(getDefautDate());
} else {
tv_end_date.setText(date);
}
}
});
dateDialog.dismiss();
}
});
dateDialog.setNoOnclickListener(new DateDialog.onNoOnclickListener() {
@Override
public void onNoClick() {
dateDialog.dismiss();
}
});
}
});
}

private void setupViews() {
tv_start_date = (TextView) findViewById(R.id.tv_start_date);
tv_end_date = (TextView) findViewById(R.id.tv_end_date);
tv_start_date.setText(getDefautDate());
tv_end_date.setText(getDefautDate());
}

public String getDefautDate() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.format(new Date());
}
}


源码:https://github.com/shaoyu00/MyApplication

2.用LoopView来实现

效果图如下:

部分关键代码:

Dialog布局主要由三个LoopView和两个按钮组成,三个LoopView分别加载年月日

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/picker_rel"
android:focusableInTouchMode="true"
android:orientation="vertical">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#FFFFFF">
<TextView
android:id="@+id/tv_cancle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="取消"
android:gravity="center|left"
android:textColor="#606060"
android:textSize="14sp"
android:paddingLeft="12dp"
android:paddingRight="12dp"
android:background="@drawable/selectableitem_background_borderless"/>
<TextView
android:id="@+id/tv_true"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="确定"
android:gravity="center|right"
android:textColor="#266497"
android:textSize="14sp"
android:paddingLeft="12sp"
android:paddingRight="12sp"
android:background="@drawable/selectableitem_background_borderless"
android:layout_alignParentRight="true"/>
</RelativeLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="216dp"
android:background="@mipmap/picker_background"
android:padding="10dp">
<View
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="1"/>
<com.weigan.loopview.LoopView
android:id="@+id/loopView_year"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="1.3" />
<com.weigan.loopview.LoopView
android:id="@+id/loopView_month"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="1" />
<com.weigan.loopview.LoopView
android:id="@+id/loopView_day"
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="1"/>
<View
android:layout_width="0px"
android:layout_height="match_parent"
android:layout_weight="1"/>
</LinearLayout>

</LinearLayout>
</RelativeLayout>


自定义的日期Dialog:加载年月日数据以及关联三个LoopView

public class DateDialog extends Dialog {

private Context context;
private ClickListenerInterface clickListenerInterface;
//private ItemSelectedListenerInterface itemSelectedListenerInterface;

LoopView loopView_year;
LoopView loopView_month;
LoopView loopView_day;
//年月日选择器打开是显示的索引位置
int yearIndex = 0;
int monthIndex=0;
int dayIndex=0;
//----------初始化日期显示值 --当天年月日
int currentYear;
int currentMonth;
int currentDay;
List<String> list_year;
List<String> list_month;
List<String> list_day;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
init();
}
@Override
public void show() {
super.show();
// 设置dialog显示动画
getWindow().setWindowAnimations(R.style.PopupAnimation);
// 设置显示位置为底部
getWindow().setGravity(Gravity.BOTTOM);
}

public DateDialog(Context context) {
super(context, R.style.MyDialog);
this.context = context;
}

public void init() {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.picker_date_lay, null);
setContentView(view);
setCanceledOnTouchOutside(true);

Window dialogWindow = getWindow();
WindowManager.LayoutParams lp = dialogWindow.getAttributes();
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
dialogWindow.setAttributes(lp);

loopView_year = (LoopView) view.findViewById(R.id.loopView_year);
loopView_month = (LoopView) view.findViewById(R.id.loopView_month);
loopView_day = (LoopView) view.findViewById(R.id.loopView_day);
TextView tvConfirm = (TextView) view.findViewById(R.id.tv_true);
TextView tvCancel = (TextView) view.findViewById(R.id.tv_cancle);
tvConfirm.setOnClickListener(new clickListener());
tvCancel.setOnClickListener(new clickListener());

//----------初始化日期显示值 --当天年月日
Calendar calendar = Calendar.getInstance();
currentYear=calendar.get(Calendar.YEAR);
currentMonth=calendar.get(Calendar.MONTH)+1;
currentDay=calendar.get(Calendar.DAY_OF_MONTH);

//-----------年 月  日  数据
list_year=new ArrayList<>();
for (int i = 1900; i <= currentYear; i++) {
list_year.add(i+"年");
}
list_month=new ArrayList<>();
for (int i = 1; i <=12; i++) {
list_month.add(i+"月");
}
list_day=new ArrayList<>();
for (int i = 1; i <= getLastDay(currentYear,currentMonth); i++) {
list_day.add(i+"日");
}
for (int i=0;i<list_year.size();i++){
String year=list_year.get(i);
if ((currentYear+"").equals(year.substring(0,year.indexOf("年")))){
yearIndex=i;
}
}
for (int i=0;i<list_month.size();i++){
String month=list_month.get(i);
if ((currentMonth+"").equals(month.substring(0,month.indexOf("月")))){
monthIndex=i;
}
}
for (int i=0;i<list_day.size();i++){
String day=list_day.get(i);
if ((currentDay+"").equals(day.substring(0,day.indexOf("日")))){
dayIndex=i;
}
}
//设置是否循环播放
//loopView_year.setNotLoop();
//loopView_month.setNotLoop();
//loopView_day.setNotLoop();
//设置原始数据
loopView_year.setItems(list_year);
loopView_month.setItems(list_month);
loopView_day.setItems(list_day);
//设置初始位置
loopView_year.setInitPosition(yearIndex);
loopView_month.setInitPosition(monthIndex);
loopView_day.setInitPosition(dayIndex);
//----------------初始化 当前年 月 日位置索引
loopView_year.setCurrentIndex(yearIndex);
loopView_month.setCurrentIndex(monthIndex);
loopView_day.setCurrentIndex(dayIndex);
//设置字体大小
loopView_year.setTextSize(18);
loopView_month.setTextSize(18);
loopView_day.setTextSize(18);

loopView_year.setListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
// 记录当前选择的年
loopView_year.setCurrentIndex(index);
int selectedYear=loopView_year.getCurrentIndex()+1900;
int selectedMonth=loopView_month.getCurrentIndex()+1;
if (selectedMonth==2){ //----------当滚动时间时  当选中的月份为2月  需要重新计算天数
List<String> newlist_day=new ArrayList<>();
for (int i = 1; i <= getLastDay(selectedYear,selectedMonth); i++) {
newlist_day.add(i+"日");
}
loopView_day.setItems(newlist_day);
}
}
});
loopView_month.setListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
loopView_month.setCurrentIndex(index);
int selectedYear=loopView_year.getCurrentIndex()+1900;
int selectedMonth=loopView_month.getCurrentIndex()+1;
List<String> newlist_day=new ArrayList<>();
for (int i = 1; i <= getLastDay(selectedYear,selectedMonth); i++) {
newlist_day.add(i+"日");
}
loopView_day.setItems(newlist_day);
}
});
loopView_day.setListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(int index) {
loopView_day.setCurrentIndex(index);
}
});

}

public void setClicklistener(ClickListenerInterface clickListenerInterface) {
this.clickListenerInterface = clickListenerInterface;
}
/*   public void setItemSelectedListener(ItemSelectedListenerInterface itemSelectedListenerInterface) {//-----------滚动时 在页面刷新日期
this.itemSelectedListenerInterface = itemSelectedListenerInterface;
}*/
private class clickListener implements View.OnClickListener {
@Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.tv_true:
clickListenerInterface.doConfirm(loopView_year,loopView_month,loopView_day);
break;
case R.id.tv_cancle:
clickListenerInterface.doCancel(loopView_year,loopView_month,loopView_day);
break;
}
}
}
/* private class itemSelectedListener implements OnItemSelectedListener {
@Override
public void onItemSelected(int index) {

}
}*/
public interface ClickListenerInterface {
void doConfirm(LoopView loopView_year, LoopView loopView_month, LoopView loopView_day);
void doCancel(LoopView loopView_year, LoopView loopView_month, LoopView loopView_day);
}
/*  public interface ItemSelectedListenerInterface {
void select();
}
*/
/**
* 判断是否闰年
*
* @param year
* @return
*/
private static boolean isLeapYear(int year) {
return (year % 100 == 0 && year % 400 == 0) || (year % 100 != 0 && year % 4 == 0);
}

/**
* 获取特定年月对应的天数
*
* @param year
* @param month
* @return
*/
private static int getLastDay(int year, int month) {
if (month == 2) {
// 2月闰年的话返回29,防止28
return isLeapYear(year) ? 29 : 28;
}
// 一三五七八十腊,三十一天永不差
return month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 ? 31 : 30;
}
}


在Activity里代码实现:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

@BindView(R.id.start_time_year)
TextView startTimeYear;
@BindView(R.id.start_time_month)
TextView startTimeMonth;
@BindView(R.id.start_time_day)
TextView startTimeDay;
@BindView(R.id.start_time)
LinearLayout startTime;
@BindView(R.id.end_time_year)
TextView endTimeYear;
@BindView(R.id.end_time_month)
TextView endTimeMonth;
@BindView(R.id.end_time_day)
TextView endTimeDay;
@BindView(R.id.end_time)
LinearLayout endTime;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);//绑定ButterKnife
initData();
}

private void initData() {
//----------初始化日期显示值 --当天年月日
Calendar calendar = Calendar.getInstance();
startTimeYear.setText(calendar.get(Calendar.YEAR) + "");
startTimeMonth.setText((calendar.get(Calendar.MONTH) + 1) + "");
startTimeDay.setText(calendar.get(Calendar.DAY_OF_MONTH) + "");
endTimeYear.setText(calendar.get(Calendar.YEAR) + "");
endTimeMonth.setText((calendar.get(Calendar.MONTH) + 1) + "");
endTimeDay.setText(calendar.get(Calendar.DAY_OF_MONTH) + "");
}

@OnClick({R.id.start_time, R.id.end_time})
public void onClick(View view) {
switch (view.getId()) {
case R.id.start_time:
int id = 1;
String before_start_year = startTimeYear.getText().toString().trim();
String before_start_month = startTimeMonth.getText().toString().trim();
String before_start_day = startTimeDay.getText().toString().trim();
showTimeDialog(id, before_start_year, before_start_month, before_start_day);
break;
case R.id.end_time:
int idd = 2;
String before_end_year = endTimeYear.getText().toString().trim();
String before_end_month = endTimeMonth.getText().toString().trim();
String before_end_day = endTimeDay.getText().toString().trim();
showTimeDialog(idd, before_end_year, before_end_month, before_end_day);
break;
}
}

private void showTimeDialog(final int id, final String before_year, final String before_month, final String before_day) {
final DateDialog confirmDialog = new DateDialog(MainActivity.this);
confirmDialog.show();
confirmDialog.setClicklistener(new DateDialog.ClickListenerInterface() {
@Override
public void doConfirm(LoopView loopView_year, LoopView loopView_month, LoopView loopView_day) {
switch (id) {
case 1:
startTimeYear.setText(loopView_year.getCurrentIndex() + 1900 + "");
startTimeMonth.setText(loopView_month.getCurrentIndex() + 1 + "");
startTimeDay.setText(loopView_day.getCurrentIndex() + 1 + "");
confirmDialog.dismiss();
break;
case 2:
endTimeYear.setText(loopView_year.getCurrentIndex() + 1900 + "");
endTimeMonth.setText(loopView_month.getCurrentIndex() + 1 + "");
endTimeDay.setText(loopView_day.getCurrentIndex() + 1 + "");
confirmDialog.dismiss();
break;
}

}

@Override
public void doCancel(LoopView loopView_year, LoopView loopView_month, LoopView loopView_day) {
switch (id) {
case 1:
startTimeYear.setText(before_year);
startTimeMonth.setText(before_month);
startTimeDay.setText(before_day);
confirmDialog.dismiss();
break;
case 2:
endTimeYear.setText(before_year);
endTimeMonth.setText(before_month);
endTimeDay.setText(before_day);
confirmDialog.dismiss();
break;
}

}
});
}
}


源码地址:https://github.com/shaoyu00/DatePicker
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息