
在开发中可能会遇到某些情况下需要用到日历的功能,并且还要在日历上加标签什么的,最重要的就是androID自带的日历由于各个系统版本不同导致日历的样式也不同,这样就会导致使用起来比较麻烦..而且在日历中加标签也不好实现...所以很多时候日历都是自己去实现的...由于自定义日历会比较麻烦...这里就教大家使用GrIDVIEw来实现,主要是我们比较熟悉这个控件...到时候也可以根据自己的情况进行封装为自定义view
下面就先看看效果图.由于是从项目中抽取出来的,某些地方定制性比较强,可以根据需求自行修改
效果图
图中的红点就是标签,蓝色背景就是选中的意思.
下面开始撸代码:
先上核心的GrIDVIEw的适配器:
Calendaradapter.java
/** * 日历grIDvIEw中的每一个item显示的textvIEw */public class Calendaradapter extends BaseAdapter { private static String TAG = "Calendaradapter"; private boolean isLeapyear = false; //是否为闰年 private int daysOfMonth = 0; //某月的天数 private int dayOfWeek = 0; //具体某一天是星期几 private int lastDaysOfMonth = 0; //上一个月的总天数 private Context context; private String[] dayNumber = new String[42]; //一个grIDvIEw中的日期存入此数组中 private SpecialCalendar sc = null; private int currentYear = 0; private int currentMonth = 0; /** * 当前选中的日期位置 */ private int currentFlag = -1; /** * 当前选中天的字符串 例:20170830 */ private String currentDayStr; private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-d"); private Set<Integer> schDateTagFlag = new ArraySet<>(); //存储当月所有的日程日期(标签) private String showYear = ""; //用于在头部显示的年份 private String showMonth = ""; //用于在头部显示的月份 private String animalsYear = ""; private String leapMonth = ""; //闰哪一个月 private Set<String> mSet = null; /** * 距离当前月的差(上一个月-1,当前月0,下一个月+1) */ private int jumpMonth = 0; public Calendaradapter(Context context,int year,int month,String currentDayStr) { this.context = context; sc = new SpecialCalendar(); currentYear = year; currentMonth = month; //得到跳转到的月份 this.currentDayStr = currentDayStr; getCalendar(currentYear,currentMonth); } @OverrIDe public int getCount() { return dayNumber.length; } @OverrIDe public Object getItem(int position) { return position; } @OverrIDe public long getItemID(int position) { return position; } @OverrIDe public VIEw getVIEw(int position,VIEw convertVIEw,VIEwGroup parent) { VIEwHolder myVIEwHolder = null; if (convertVIEw == null || convertVIEw.getTag() == null) { convertVIEw = LayoutInflater.from(context).inflate(R.layout.item_select_time,null); myVIEwHolder = new VIEwHolder(convertVIEw); convertVIEw.setTag(myVIEwHolder); } else { myVIEwHolder = (VIEwHolder) convertVIEw.getTag(); } myVIEwHolder.mIDTvItemSelectTimeDay.setText(dayNumber[position]); myVIEwHolder.mIDTvItemSelectTimeDay.setTextcolor(color.GRAY);//不是当前月为灰 if (position < daysOfMonth + dayOfWeek && position >= dayOfWeek) { // 当前月信息显示 myVIEwHolder.mIDTvItemSelectTimeDay.setTextcolor(color.BLACK);// 当月字体设黑 myVIEwHolder.mIDTvItemSelectTimeDay.setTag(true);// 当月字体设黑 }else { myVIEwHolder.mIDTvItemSelectTimeDay.setTag(false);// 当月字体设黑 } if (currentFlag != -1 && currentFlag == position) { //设置当天的背景 myVIEwHolder.mIDTvItemSelectTimeDay.setBackgroundResource(R.color.mainMenu); myVIEwHolder.mIDTvItemSelectTimeDay.setTextcolor(color.WHITE); } else { myVIEwHolder.mIDTvItemSelectTimeDay.setBackgroundcolor(0); } //显示小圆点 if (schDateTagFlag != null && schDateTagFlag.size() > 0) { if (schDateTagFlag.contains(position)) { if (myVIEwHolder.mIDimgItemSelectTimelogo.getVisibility()!=VIEw.VISIBLE) { myVIEwHolder.mIDimgItemSelectTimelogo.setVisibility(VIEw.VISIBLE); } } else { if (myVIEwHolder.mIDimgItemSelectTimelogo.getVisibility()!=VIEw.GONE) { myVIEwHolder.mIDimgItemSelectTimelogo.setVisibility(VIEw.GONE); } } } else { if (myVIEwHolder.mIDimgItemSelectTimelogo.getVisibility()!=VIEw.GONE) { myVIEwHolder.mIDimgItemSelectTimelogo.setVisibility(VIEw.GONE); } } return convertVIEw; } /** * 下一个月 */ public voID addMonth() { jumpMonth++; } /** * 上一个月 */ public voID lessMonth() { jumpMonth--; } /** * 更新日历数据 */ public voID upDataMonth() { int stepYear; int stepMonth = currentMonth + jumpMonth; if (stepMonth > 0) { //下一个月 if (stepMonth % 12 == 0) { stepYear = currentYear + stepMonth / 12 - 1; stepMonth = 12; } else { stepYear = currentYear + stepMonth / 12; stepMonth = stepMonth % 12; } } else { //上一个月 stepYear = currentYear - 1 + stepMonth / 12; stepMonth = stepMonth % 12 + 12; } getCalendar(stepYear,stepMonth); } /** * 得到某年的某月的天数且这月的第一天是星期几 * * @param year * @param month */ private voID getCalendar(int year,int month) { isLeapyear = sc.isLeapYear(year); //是否为闰年 daysOfMonth = sc.getDaysOfMonth(isLeapyear,month); //某月的总天数 dayOfWeek = sc.getWeekdayOfMonth(year,month); //某月第一天为星期几 lastDaysOfMonth = sc.getDaysOfMonth(isLeapyear,month - 1); //上一个月的总天数 getWeek(year,month); } /** * 将一个月中的每一天的值添加入数组dayNuber中 * * @param year * @param month */ private voID getWeek(int year,int month) { schDateTagFlag.clear(); currentFlag = -1; int j = 1; //得到当前月的所有日程日期(这些日期需要标记) for (int i = 0; i < dayNumber.length; i++) { if (i < dayOfWeek) { //前一个月 int temp = lastDaysOfMonth - dayOfWeek + 1; dayNumber[i] = (temp + i) + ""; } else if (i < daysOfMonth + dayOfWeek) {//本月 int day = i - dayOfWeek + 1; //得到的日期 dayNumber[i] = i - dayOfWeek + 1 + ""; //对于当前月才去标记当前日期 String yearStr = String.valueOf(year); String monthStr =getStr(String.valueOf(month),2); String dayStr =getStr(String.valueOf(day),2); String timeAll = yearStr + monthStr + dayStr; if (timeAll.equals(currentDayStr)) {//判断选中的位置 currentFlag = i; } if (mSet != null && mSet.size() > 0) { for (String s : mSet) {//迭代器遍历判断是否需要带标签 if (timeAll.equals(s)) { schDateTagFlag.add(i); } } } setShowYear(yearStr); setShowMonth(String.valueOf(month)); } else { //下一个月 dayNumber[i] = j + ""; j++; } } } /** * 获取当前时间 样式:20170830 * @param position * @return */ public String getItemTime(int position) { String month = getStr(getShowMonth(),2); String day = getStr(getDateByClickItem(position),2); return getShowYear() + month + day; } /** * 保留n位整数,不足前面补0 * * @param file String * @param bit 位数 * @return */ public static String getStr(String file,int bit) { while (file.length() < bit) file = "0" + file; return file; } /** * 点击每一个item时返回item中的日期 * * @param position * @return */ public String getDateByClickItem(int position) { return dayNumber[position]; } /** * 在点击grIDVIEw时,得到这个月中第一天的位置 * * @return */ public int getStartPositon() { return dayOfWeek + 7; } /** * 在点击grIDVIEw时,得到这个月中最后一天的位置 * * @return */ public int getEndposition() { return (dayOfWeek + daysOfMonth + 7) - 1; } public String getShowYear() { return showYear; } public voID setShowYear(String showYear) { this.showYear = showYear; } public String getShowMonth() { return showMonth; } public voID setShowMonth(String showMonth) { this.showMonth = showMonth; } public String getAnimalsYear() { return animalsYear; } public voID setAnimalsYear(String animalsYear) { this.animalsYear = animalsYear; } public String getLeapMonth() { return leapMonth; } public voID setLeapMonth(String leapMonth) { this.leapMonth = leapMonth; } public Set<String> getSet() { return mSet; } public voID setSet(Set<String> set) { mSet = set; } static class VIEwHolder { @BindVIEw(R.ID.ID_img_item_select_time_logo) ImageVIEw mIDimgItemSelectTimelogo; @BindVIEw(R.ID.ID_tv_item_select_time_day) TextVIEw mIDTvItemSelectTimeDay; VIEwHolder(VIEw vIEw) { ButterKnife.bind(this,vIEw); } }}日历工具类:
/** * 日历工具类 */public class SpecialCalendar { private int daysOfMonth = 0; //某月的天数 private int dayOfWeek = 0; //具体某一天是星期几 /** * 判断是否为闰年 * @param year * @return */ public boolean isLeapYear(int year) { if (year % 100 == 0 && year % 400 == 0) { return true; } else if (year % 100 != 0 && year % 4 == 0) { return true; } return false; } /** * 得到某月有多少天数 * @param isLeapyear * @param month * @return */ public int getDaysOfMonth(boolean isLeapyear,int month) { switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: daysOfMonth = 31; break; case 4: case 6: case 9: case 11: daysOfMonth = 30; break; case 2: if (isLeapyear) { daysOfMonth = 29; } else { daysOfMonth = 28; } } return daysOfMonth; } /** * 指定某年中的某月的第一天是星期几 * @param year * @param month * @return */ public int getWeekdayOfMonth(int year,int month){ Calendar cal = Calendar.getInstance(); cal.set(year,month-1,1); dayOfWeek = cal.get(Calendar.DAY_OF_WEEK)-1; return dayOfWeek; } } 布局文件:
<linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:orIEntation="vertical"> <include layout="@layout/layout_public_finish_menu" /> <linearLayout androID:layout_wIDth="match_parent" androID:layout_height="40dp" androID:background="@color/bg_home_gone_menu" androID:gravity="center" androID:orIEntation="horizontal" > <ImageVIEw androID:ID="@+ID/ID_img_select_time_less" androID:layout_wIDth="wrap_content" androID:layout_height="match_parent" androID:layout_weight="1" androID:padding="5dp" androID:src="@mipmap/ic_sd_time_less" androID:background="@drawable/selector_public_btn_bg" /> <TextVIEw androID:ID="@+ID/ID_tv_select_time_show" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_weight="4" androID:gravity="center" androID:text="年月" androID:textcolor="@color/white" androID:textSize="@dimen/default_big" /> <ImageVIEw androID:ID="@+ID/ID_img_select_time_add" androID:layout_wIDth="wrap_content" androID:layout_height="match_parent" androID:layout_weight="1" androID:padding="5dp" androID:src="@mipmap/ic_sd_time_add" androID:background="@drawable/selector_public_btn_bg" /> </linearLayout> <GrIDVIEw androID:ID="@+ID/ID_gv_select_item" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:background="@drawable/bg_rectangle_null_black_1" androID:clickable="true" androID:gravity="center" androID:layout_gravity="center" androID:clipChildren="true" androID:ListSelector="@null" androID:numColumns="7" androID:padding="1dp" androID:layout_margin="5dp" androID:stretchMode="columnWIDth" /></linearLayout>
Item布局
<relativeLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:background="@drawable/bg_rectangle_null_black_1"> <TextVIEw androID:ID="@+ID/ID_tv_item_select_time_day" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:gravity="center" androID:text="天" androID:textSize="@dimen/default_big" androID:layout_margin="1dp" androID:textStyle="bold" /> <ImageVIEw androID:ID="@+ID/ID_img_item_select_time_logo" androID:layout_wIDth="5dp" androID:layout_height="5dp" androID:layout_margin="3dp" androID:src="@drawable/shap_doorbell_oval_red" androID:visibility="gone" /></relativeLayout>
布局只供参考...可以根据需求进行修改
下面就看看简单的调用
//传入当前的年,月..已经选中的时间(20170830) mAdapter = new Calendaradapter(mContext,year_c,month_c,currentDayStr); mIDGvSelectItem.setAdapter(mAdapter); /** * GrIDVIEw Item的点击事件 */ private class MyGvListener implements AdapterVIEw.OnItemClickListener { @OverrIDe public voID onItemClick(AdapterVIEw<?> parent,VIEw vIEw,int position,long ID) { TextVIEw mTv = (TextVIEw) vIEw.findVIEwByID(R.ID.ID_tv_item_select_time_day); boolean isOnClick = (boolean) mTv.getTag(); if (isOnClick) { String time = mAdapter.getItemTime(position); Intent mIntent = getIntent(); mIntent.putExtra("fileDate",time); setResult(AppStart.SDVA_SDTA,mIntent); finish(); Log.i(TAG,"当前选择的时间:" + time); } } } /** * 点击事件逻辑处理 */ private class MyListener implements VIEw.OnClickListener { @OverrIDe public voID onClick(VIEw v) { switch (v.getID()) { //上一个月 case R.ID.ID_img_select_time_less: mAdapter.lessMonth(); mHandler.sendEmptyMessage(UPDATA_TIME); addTextTotopTextVIEw(mIDTvSelectTimeShow); break; //下一个月 case R.ID.ID_img_select_time_add: mAdapter.addMonth(); mHandler.sendEmptyMessage(UPDATA_TIME); addTextTotopTextVIEw(mIDTvSelectTimeShow); break; } } }private Set<String> dayEventCount = new HashSet<>();//设置需要显示标签的实际 mAdapter.setSet(dayEventCount);//更新 @OverrIDe protected voID uiHandlerMessage(Message msg) { switch (msg.what) { case UPDATA_TIME: mAdapter.upDataMonth(); mAdapter.notifyDataSetChanged(); break; } }调用部分的代码由于是从项目中直接复制出来的..代码的前后没有什么关联性,主要是说明功能的..请根据自己的项目进行调整..
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
以上是内存溢出为你收集整理的Android使用GridView实现日历的方法全部内容,希望文章能够帮你解决Android使用GridView实现日历的方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)