哈哈,又要更新博客了+_+!
这一次发一个日历选择器吧!
说实话,看到需求那一刻,我绝对是崩溃的,不过还好有github这个大佬罩着我,所以为了避免重复造轮子,我就去上面找了一下日历选择器,一搜一大把,刚开始挺高兴的,结果后来越看脸越黑,没一个符合我的需求嘛,怎么搞得。。。((╯‵□′)╯︵┻━┻)后来没办法了,只能自己写了,神啊,给我力量吧!!!
首先确定一下需要的效果:其实就是多选日期,听起来挺简单的,可是做起来真的要崩溃啊!嗷呜~~(效果如下)

网上是挺多日期多选的三方,但是很多改起来费时间,而且还有用Fragment写出来的,一下缓存200个页面,我的心里有10000只XX马奔腾而过啊,不过这个日历还是很好做的。
1.首先,今天之前的日期不能选择,并且呈灰色显示
2.选中的日期,连续2个不显示色带,连续3个要显示色带
确定了这两个要求,那么久开始敲代码吧!
还是和之前的自定义View一样,确定自定义属性:

  1. 看图片就知道选中颜色和色带颜色这个是必须的吧
  2. 然后就是字体的大小
  3. 可以选择的字体颜色
  4. 不可以选择的字体颜色

右上角那个切换月份的ImageView可以忽略不写进去,不然这个控件的逻辑就会变的复杂,通用性不强
先说一下画控件的思路吧:

  1. 先用一行画年月
  2. 画星期
  3. 画选中的圆形以及色带
  4. 然后计算日期做成一堆List数据
  5. 然后根据数据使用for循环画上去(ps:5.0的系统使用递归函数画没有问题,但是5.0以下的使用递归会抛出堆栈溢出,原因是递归太深了,所以我改成了for循环)
  6. 抛出一些方法

首先是定义的属性:

private Context mContext;//定义属性private final int TOTAL_COLUMS = 7;//列数private int TOTAL_ROW = 0;//行数private int mSelectColor;//默认红色private int num = 31;//定义可以选择的天数private int mColumWidth;//列宽private int mColumHeith;//列高private int textSize = 28;//字体大小private int enableColor;//可编辑字体颜色private int unenableColor;//不可编辑字体颜色private int mBgSelectColor;//色带颜色private int MONTH = 0;//定义画笔private Paint mSelectPaint;private Paint mContiuousPaint;private Paint mMonthPaint;private Paint mWeekPaint;private Paint mTextPaint;private int mViewWidth;//视图宽度private int mViewHeigh;//视图高度//其他属性private int curYear;private int curMonth;private int MaxSize = 0;private boolean isFirst = true;private boolean canClick = true;private boolean needClear = true;private boolean canEdit = true;private List<DateModel> mDatas = new ArrayList<>();private List<String> selectDatas = new ArrayList<>();private OnDateClickListener dateClickListener;

定义完属性之后就开始重写View的构造函数,用到自定义属性,所以就要重写3个构造函数
自定义的属性:

<declare-styleable name="CalendarSelectView"><attr name="selectColor" format="color"/><attr name="CalendartextSize" format="dimension"/><attr name="enableColor" format="color"/><attr name="unenableColor" format="color"/><attr name="bgSelectColor" format="color"/></declare-styleable>

重写的构造函数:

public CalendarSelectView(Context context) {this(context, null);}public CalendarSelectView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public CalendarSelectView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mContext = context;TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CalendarSelectView);mSelectColor = a.getColor(R.styleable.CalendarSelectView_selectColor, Color.parseColor("#1FCD6D"));textSize = a.getDimensionPixelOffset(R.styleable.CalendarSelectView_CalendartextSize,DensityUtil.sp2px(context, 14));enableColor = a.getColor(R.styleable.CalendarSelectView_enableColor, Color.BLACK);unenableColor = a.getColor(R.styleable.CalendarSelectView_unenableColor, Color.LTGRAY);mBgSelectColor = a.getColor(R.styleable.CalendarSelectView_bgSelectColor, Color.parseColor("#D6FFE9"));a.recycle();init();}

然后是初始化画笔:

public void init() {mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mTextPaint.setTextSize(textSize);mMonthPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mMonthPaint.setTextSize(textSize);mMonthPaint.setColor(Color.GRAY);mWeekPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mWeekPaint.setColor(Color.BLACK);mWeekPaint.setStyle(Paint.Style.STROKE);mWeekPaint.setTextSize(DensityUtil.sp2px(mContext, 14));mSelectPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mSelectPaint.setStyle(Paint.Style.FILL);mSelectPaint.setColor(mSelectColor);mContiuousPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mContiuousPaint.setStyle(Paint.Style.FILL);mContiuousPaint.setColor(mBgSelectColor);setOnTouchListener(this);}

搞定这些后就要开始测量布局了:

@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int widthSize = MeasureSpec.getSize(widthMeasureSpec);mViewWidth = widthSize;mColumWidth = mViewWidth / TOTAL_COLUMS;mColumHeith = mColumWidth - DensityUtil.dip2px(mContext, 5);TOTAL_ROW = (DateUtils.getMonthOfAllDay(curYear, curMonth) / 7) + 2;mViewHeigh = TOTAL_ROW * mColumHeith;MaxSize = (TOTAL_ROW - 2) * 7;setMeasuredDimension(mViewWidth, mViewHeigh);}

首先解释一下,宽度就是铺满屏幕的,受父布局的控制,然后就是计算每一列的列宽用整个控件的宽度直接除7得到平均的宽,然后列高就是列宽 - 5dp转成的px,然后才开始算总的行数,因为年月和星期用了2行,所以要加上2,日期需要的行数就是当月的天数 / 7,这个应该不难吧,然后就开始算控件的高度了,这个简单啦,直接用 行数 * 列高,最后调用一下setMeasureDimension();就打算测量结束了。
长话短说吧,测量完了就开始要画了,那么就直接重写onDraw(Canvas canvas)就好了:

@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int week = DateUtils.getDayofWeek(calendar, 1);calendar.set(Calendar.DATE, 1);calendar.add(Calendar.DAY_OF_WEEK, -week + 1);drawMonth(canvas);drawWeek(canvas);drawRow(canvas);}

解释一下:
drawMonth就是画年月的

private void drawMonth(Canvas canvas) {Rect c = new Rect();String text = String.valueOf(curMonth + 1) + "月  " + String.valueOf(curYear);mMonthPaint.getTextBounds(text, 0, text.length(), c);canvas.drawText(text, 30, (mColumWidth + c.height()) / 3, mMonthPaint);}

drawWeek就是画星期的

String[] week = new String[]{"日", "一", "二", "三", "四", "五", "六"};private void drawWeek(Canvas canvas) {for (int i = 0; i < week.length; i++) {Rect bound = new Rect();mWeekPaint.getTextBounds(week[i], 0, week[i].length(), bound);int x = i * mColumWidth + (mColumWidth - bound.width()) / 2;canvas.drawText(week[i], x, mColumHeith / 2 + mColumHeith, mWeekPaint);}}

drawRow就是画日期的

private void drawRow(Canvas canvas) {for (int i = 2; i < TOTAL_ROW; i++) {calendar.setTime(calendar.getTime());if (mDatas.size() < MaxSize) {initData(calendar, 1, i);}}if (needClear) {clearData(mDatas);needClear = false;}if (selectDatas.size() > 0) {if (!canEdit) {findSelectData();}else{if (isFirst) {
//                    dealData(selectDatas, 0, 0);dealData();isFirst = false;}}}drawDay(canvas);}//处理数据private void dealData(){for (int i=0;i<mDatas.size();i++){for (int j=0;j<selectDatas.size();j++){if (mDatas.get(i).getDate().equals(selectDatas.get(j))){mDatas.get(i).setSelect(true);break;}else{if (j == selectDatas.size() - 1){mDatas.get(i).setSelect(false);}}}}}//清除数据//清理data的选中数据private void clearData(List<DateModel> datas){for (int i=0;i<datas.size();i++){datas.get(i).setSelect(false);}}

可能大家会有点看不动这个drawRow里面的东西,其实这个方法我是后面改过来了,重要的地方是循环drawDay这个两个方法,循环里面其实是为了算日期的,按照顺序把日期算出来,然后存成一个List:

private void initData(Calendar time, int colum, int row) {DateModel model = new DateModel(time.getTime());model.setColums(colum);model.setRow(row);long diff = time.getTime().getTime() - System.currentTimeMillis();long day = (long) Math.ceil(diff / (3600 * 24 * 1000));//天数距离当前天数boolean isCurrentMonth = DateUtils.isCurrentMonthDay(time, curYear, MONTH);if (day >= 0 && day < num - 1 && isCurrentMonth) {//当天或者最大可选择数目之间则可编辑model.setCanSelect(true);} else {model.setCanSelect(false);}if (!DateUtils.isCurrentMonthDay(time, curYear, MONTH)) {model.setCurrentMonth(false);} else {model.setCurrentMonth(true);}mDatas.add(model);//保存到listtime.add(Calendar.DATE, 1);if (colum != 7) {colum += 1;initData(time, colum, row);}}

其实每一个日期都是一个实体,根据当天日期和传入的可选择的最大天数去判断是否可以选择,可以的就把实体的canselect修改成true,否则就是false,这样方便我们记录它的信息:

private class DateModel {private String date;private boolean canSelect;private int colums;private int row;private boolean isSelect;private boolean isCurrentMonth;private int selectColor = Color.parseColor("#F24949");/*** 状态标记值* 1 左边开始圆形带色带* -1 色带* 2 右边结束圆形带色带* 3 不带色带的圆形*/private int area;public DateModel(Date date) {SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");this.date = format.format(date);}public boolean isCurrentMonth() {return isCurrentMonth;}public void setCurrentMonth(boolean currentMonth) {isCurrentMonth = currentMonth;}public int getArea() {return area;}public void setArea(int area) {this.area = area;}public int getDay() {if (TextUtils.isEmpty(date)) {return 0;} else {return Integer.parseInt(date.substring(6, date.length()));}}public int getSelectColor() {return selectColor;}public void setSelectColor(int selectColor) {this.selectColor = selectColor;}public String getDate() {return date;}public void setDate(String date) {this.date = date;}public boolean isSelect() {return isSelect;}public void setSelect(boolean select) {isSelect = select;}public int getRow() {return row;}public void setRow(int row) {this.row = row;}public int getColums() {return colums;}public void setColums(int colums) {this.colums = colums;}public boolean isCanSelect() {return canSelect;}public void setCanSelect(boolean canSelect) {this.canSelect = canSelect;}public String toString() {return date;}}

计算好了之后就开始drawDay()了,在drawDay()中我循环这个算好的日期的list,然后一边算每一个日期的位置然后画出来:

private void drawDay(Canvas canvas) {for (int i = 0; i < mDatas.size(); i++) {Rect bound = new Rect();String text = String.valueOf(mDatas.get(i).getDay() == 0 ? "" : mDatas.get(i).getDay());mTextPaint.getTextBounds(text, 0, text.length(), bound);int x = (mDatas.get(i).getColums() - 1) * mColumWidth + (mColumWidth - bound.width()) / 2;int y = 2 * mColumHeith + bound.height() + ((mDatas.get(i).getRow() - 2) * mColumHeith);mTextPaint.setColor(mDatas.get(i).isCanSelect() ? enableColor : unenableColor);int centerx = (mDatas.get(i).getColums() - 1) * mColumWidth + (mColumWidth / 2);int centery = 2 * mColumHeith + (bound.height() / 2) + ((mDatas.get(i).getRow() - 2) * mColumHeith);if (mDatas.get(i).isCanSelect()) {if (canEdit) {if (!mDatas.get(i).isSelect()) {mSelectPaint.setColor(Color.TRANSPARENT);mTextPaint.setColor(enableColor);} else {mSelectPaint.setColor(mSelectColor);mTextPaint.setColor(Color.WHITE);}drawCircle(canvas, centerx, centery, mSelectPaint);} else {int left = (mDatas.get(i).getColums() - 1) * mColumWidth;int top = 2 * mColumHeith - (mColumHeith / 2) + (bound.height() / 2) +((mDatas.get(i).getRow() - 2) * mColumHeith);mContiuousPaint.setColor(mBgSelectColor);if (mDatas.get(i).isSelect()) {if (mDatas.get(i).getArea() == -1) {mTextPaint.setColor(enableColor);//画色带drawRibbon(canvas, left, top, mDatas.get(i).getArea(), mContiuousPaint);} else if (mDatas.get(i).getArea() == 1 || mDatas.get(i).getArea() == 2|| mDatas.get(i).getArea() == 3) {//画圆mSelectPaint.setColor(mSelectColor);mTextPaint.setColor(Color.WHITE);drawRibbon(canvas, left, top, mDatas.get(i).getArea(), mContiuousPaint);drawCircle(canvas, centerx, centery, mSelectPaint);}}}}if (mDatas.get(i).isCurrentMonth()) {canvas.drawText(text, x, y, mTextPaint);} else {canvas.drawText("", x, y, mTextPaint);}}}

通过实体里面记录的colums以及rows去计算位置并且判断哪些日期可以被选择,哪些不可以,然后把画笔的颜色根据状态去改变,最后画出来,在画的时候还要判断是否可以编辑(canEdit)状态,true的话我们就要判断这个实体的是否被选中,选中的话,那么画笔就要改变颜色,然后我们先画圆跟色带,最后才画文字,不然文字会被圆或者色带给遮挡住,在画圆和色带的时候我们需要判断每个实体的area,根据area的值去画,具体的在实体类上面有写着area的解释
画圆和色带的方法我也贴上来:

    private void drawCircle(Canvas canvas, int centerX, int centerY, Paint paint) {canvas.drawCircle(centerX, centerY, (float) (mColumHeith / 2 * 0.85), paint);}private void drawRibbon(Canvas canvas, int x, int y, int type, Paint paint) {Rect ribbon = new Rect();int interval = (int) ((mColumHeith - (mColumHeith * 0.7)) / 2);if (type == -1 || type == 2) {ribbon.left = x;} else if (type == 1) {//画右边一半的色带ribbon.left = x + (mColumWidth / 2);}ribbon.top = y + interval;if (type == -1 || type == 1) {ribbon.right = x + mColumWidth;} else if (type == 2) {//画左边一半的色带ribbon.right = x + (mColumWidth / 2);}ribbon.bottom = y + mColumHeith - interval;canvas.drawRect(ribbon, paint);}

处理选中数据的方法:

private void findSelectData(){for(int i=0;i<mDatas.size();i++){for(int j = 0;j < selectDatas.size();j++){if (mDatas.get(i).toString().equals(selectDatas.get(j))){mDatas.get(i).setSelect(true);if (i != 0){if (mDatas.get(i - 1).isSelect()){if (mDatas.get(i - 1).getArea() != 2){mDatas.get(i).setArea(-1);}else{mDatas.get(i).setArea(1);}if (mDatas.get(i).isCanSelect() && mDatas.get(i - 1).isCanSelect() && mDatas.get(i - 1).getArea() == 3) {mDatas.get(i - 1).setArea(1);}}else{mDatas.get(i).setArea(3);}}else{mDatas.get(i).setArea(3);}break;}else{if (i != 0) {if (mDatas.get(i - 1).isSelect()) {if (j == selectDatas.size() - 1) {mDatas.get(i).setSelect(false);if (i > 1) {if (mDatas.get(i - 2).isSelect() && mDatas.get(i - 2).getArea() == -1) {mDatas.get(i - 1).setArea(2);} else {mDatas.get(i - 1).setArea(3);if (mDatas.get(i - 2).isSelect()) {mDatas.get(i - 2).setArea(3);}}} else {if (mDatas.get(i - 1).isSelect()) {mDatas.get(i - 1).setArea(3);}}break;}}}}}}}

然后现在主要就是抛出方法了,从外面传数据进来控件需要处理的方法:

/*** 刷新日期*/public void setDate(Calendar calendar, List<String> datas) {this.calendar = calendar;selectDatas.clear();selectDatas.addAll(datas);fillData(selectDatas);curYear = calendar.get(Calendar.YEAR);curMonth = calendar.get(Calendar.MONTH);MONTH = curMonth;mDatas.clear();//重新测量布局requestLayout();}//排序Listpublic void fillData(List<String> data) {for (int i = 0; i < data.size(); i++) {for (int j = i + 1; j < data.size(); j++) {if (Integer.parseInt(data.get(i)) > Integer.parseInt(data.get(j))) {String temp = data.get(i);data.set(i, data.get(j));data.set(j, temp);}}}}

恩~差点漏了,还有一个重点,就是控件的触摸事件:

@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_UP:if (canEdit && canClick) {int colums = (int) Math.ceil(event.getX() / mColumWidth);int row = (int) Math.ceil(event.getY() / mColumHeith) - 1;for (int i = 0; i < mDatas.size(); i++) {if (mDatas.get(i).getColums() == colums && mDatas.get(i).getRow() == row&& mDatas.get(i).isCanSelect()) {if (mDatas.get(i).isSelect()) {mDatas.get(i).setSelect(false);if (dateClickListener != null) {dateClickListener.onUnSelect(mDatas.get(i).toString());}} else {mDatas.get(i).setSelect(true);if (dateClickListener != null) {dateClickListener.onSelect(mDatas.get(i).toString());}}postInvalidate();}}}break;}return true;}

我这里直接用了手指抬起的事件,在抬起的时候获取X和Y,然后计算当前的所点击的行和列,然后对应到实体的行和列,符合就标记为选中状态,然后调用postInvalidate()刷新控件,然后再控件里面写一个点击的回调OnDateClickListener,然后在Touch事件中调用,就可以了

public interface OnDateClickListener {void onSelect(String date);void onUnSelect(String date);}

大功告成 = =,终于写完了,继续敲代码去了(=^ ^=)

一直忘了还有一个工具类没有放上来,是我的锅~~,重新补上了

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;/*** Date工具类* Created by Thong on 2017/6/8.*/public class DateUtils {/*** 获取月份第一天的星期*/public static int getFirstDayofWeek(){Calendar calendar = Calendar.getInstance();calendar.set(Calendar.DAY_OF_MONTH,1);return calendar.get(Calendar.DAY_OF_WEEK);}/*** 获取某一天的星期*/public static int getDayofWeek(Calendar calendar, int day){calendar.set(Calendar.DAY_OF_MONTH,day);return calendar.get(Calendar.DAY_OF_WEEK);}/*** 获取某个月的第一天的星期*/public static int getMonthDayOfWeek(Date date){Calendar calendar = Calendar.getInstance();calendar.setTime(date);calendar.set(Calendar.DAY_OF_MONTH,1);return calendar.get(Calendar.DAY_OF_WEEK);}/*** 获取当前日期是该月的第几天** @return*/public static int getCurrentDayOfMonth() {return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);}/*** 获取当前日期是该周的第几天** @return*/public static int getCurrentDayOfWeek() {return Calendar.getInstance().get(Calendar.DAY_OF_WEEK);}/*** 根据传入的年份和月份,判断上一个月有多少天** @param year* @param month* @return*/public static int getLastDaysOfMonth(int year, int month) {int lastDaysOfMonth = 0;if (month == 1) {lastDaysOfMonth = getDaysOfMonth(year - 1, 12);} else {lastDaysOfMonth = getDaysOfMonth(year, month - 1);}return lastDaysOfMonth;}/*** 根据传入的年份和月份,判断当前月有多少天** @param year* @param month* @return*/public static int getDaysOfMonth(int year, int month) {switch (month) {case 0:case 2:case 4:case 6:case 7:case 9:case 11:return 31;case 1:if (isLeap(year)) {return 29;} else {return 28;}case 3:case 5:case 8:case 10:return 30;}return -1;}/*** 判断是否为闰年** @param year* @return*/public static boolean isLeap(int year) {if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {return true;}return false;}public static int getYear() {return Calendar.getInstance().get(Calendar.YEAR);}public static int getMonth() {return Calendar.getInstance().get(Calendar.MONTH) + 1;}public static int getCurrentMonthDay() {return Calendar.getInstance().get(Calendar.DAY_OF_MONTH);}public static boolean isToday(){SimpleDateFormat dateFormat = new SimpleDateFormat("dd");String day = dateFormat.format(System.currentTimeMillis());int curDay = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);return(curDay == Integer.parseInt(day));}public static boolean isCurrentMonth(){SimpleDateFormat dateFormat = new SimpleDateFormat("MM");String month = dateFormat.format(System.currentTimeMillis());int curMonth = Calendar.getInstance().get(Calendar.MONTH) + 1;return(curMonth == Integer.parseInt(month));}/*** 判断当前日期是否是当前月的日期* @param calendar* @return*/public static boolean isCurrentMonthDay(Calendar calendar, int year, int month) {return calendar.get(Calendar.YEAR) == year && calendar.get(Calendar.MONTH) == month;}public static int getMonthOfAllDay(int year,int month){Calendar calendar = Calendar.getInstance();calendar.set(year,month,1);int thismonthdays = getDaysOfMonth(year,month);int week = calendar.get(Calendar.DAY_OF_WEEK);int lastmonthdayInthismonth = week - 1;calendar.set(year,month,thismonthdays);week = calendar.get(Calendar.DAY_OF_WEEK);int nextmonthdayInthismonth = 7-week;return thismonthdays + lastmonthdayInthismonth + nextmonthdayInthismonth;}
}

安卓自定义日历选择器相关推荐

  1. 安卓自定义时间选择器_微信小程序拾色器(颜色选择器)组件

    点击上方"极客小寨",选择"置顶公众号" 第一时间关注程序猿(媛)身边的故事 大家好,我是独立开发者东东,如今在web项目中不少地方需要用到颜色选择器,比如设置 ...

  2. uni-app - 日历选择器组件(支持日期 “范围选择“ 多选 / 支持单选日期 / 自定义默认选中时间 / 弹框式 / 支持农历 )完美兼容 H5 APP 小程序,最好用的教程完整源代码插件!

    前言 网上的教程代码非常乱且都有 BUG 存在,非常难移植到自己的项目中,本文代码干净整洁注释详细. 本文提供 弹框式日历选择器组件,支持单选.范围选择日期,全端兼容无BUG! 您只需复制粘贴,保证几 ...

  3. html5 自定义 datepicker,如何使用 React 构建自定义日期选择器(3)

    本文作者:IMWeb howenhuo 未经同意,禁止转载 Datepicker 组件 构建 Datepicker 组件 要开始构建 Datepicker 组件,请将以下代码片段添加到 src/com ...

  4. 安卓自定义日期控件(仿QQ,IOS7)

    还记得上篇:高大上的安卓日期时间选择器,本篇是根据上篇修改而来,先看下qq中日期选择的效果: 鉴于目前还没有相似的开源日期控件,因此本人花费了一些时间修改了下之前的日期控件,效果如图: 虽说相似度不是 ...

  5. Unity日历选择器ZCalendar下载

    下载链接: unity日历: 操作简单,功能全面的日历选择器,可自定义初始化时间,可显示农历日期,可做静态日历显示,尺寸自适应等

  6. 【无私分享】干货!!!一个炫酷的自定义日历控件,摆脱日历时间选择烦恼,纯福利~...

    最近公司项目中有一个按日期查看信息的功能,楼主本想用之前用的wheelView将就使用的,不过产品经理有个新要求,就是点击按钮弹出的日期选择对话框必须显示农历节假日,周几什么的.这可就难为人了,倘若使 ...

  7. 纵享丝滑滑动切换的周月日历,水滴效果,丰富自定义日历样式

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QF0ojEiz-1650020556182)(https://user-gold-cdn.xitu.io/2018/2/ ...

  8. android 日历选择器(酒店专用)

    日历选择器 由于公司需求,参看了各个平台的酒店日历选择功能,手动写了一个,就当记录下,代码逻辑可能还需要再去优化下,各位小伙伴没思路的可以参考下..接下来正题. 看下实现后效果图吧.. 布局上是Rec ...

  9. 自定义日历控件背景样式

    #自定义日历控件的使用 一.DatePicker日期选择类的使用 DatePicker常用xml属性: XML属性 描述 android:calendarViewShown 设置该日期选择是否显示Ca ...

最新文章

  1. oracle clob 存储大于4000字符的字符串
  2. NanoHttpd源码分析
  3. keil编译出错关于__use_no_semihosting_swi的使用
  4. IOS中scrollsToTop问题小结
  5. VTK:可视化之CubeAxesActor
  6. 创建spring配置
  7. 使用cv::findFundamentalMat要注意的几点
  8. open_basedir restriction in effect,解决php引入文件权限问题
  9. ASP中如何在退出一个页面时自动清空session变量
  10. 利用ObjectMapper进行对象与JSON互相转化
  11. java 下载视频文件
  12. Android手机端脚本录制
  13. spring-mvc集成urule
  14. 三轴传感器、六轴传感器、九轴传感器的文章解读
  15. [附源码]java毕业设计st音乐网站论文
  16. SE5_FALSR超分辨率图像模型移植与测试
  17. 自考大专计算机专业英语翻译,大专英语自考(上册)课文翻译及习题答案(138页)-原创力文档...
  18. mysql基于WebStorm服装购物网站的设计与实现毕业设计源码281444
  19. mesh 协调器 路由器_双模网络协调器、双模路由器、双模mesh组网系统及其方法与流程...
  20. 视源股份(CVTE)亮相世界顶级计算机视觉盛会CVPR 2017

热门文章

  1. PIL之ImageFilter下的基本操作
  2. 华为手机实现语音转文字的最佳方法!不知道的看这里
  3. Dojo Toolkit 创始人谈Dojo学习
  4. 学习的一些好网站(涨姿势的)
  5. 什么是高防IP,高防IP有什么效果,使用云服务器可以接入吗?
  6. VUE图片添加角标,图片右上角或左上角添加标识
  7. 微服务做成镜像部署到容器
  8. 即席和即兴_即兴演讲即席发言的五个策略
  9. shell if else 语句 写成一行
  10. 最全模型效果评估报告上线,百度飞桨企业版EasyDL助力模型效果快速优化