android gridview日历,Android使用GridView实现日历的方法
在开发中可能会遇到某些情况下需要用到日历的功能,并且还要在日历上加标签什么的,最重要的就是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 schDateTagFlag = new ArraySet<>(); //存储当月所有的日程日期(标签)
private String showYear = ""; //用于在头部显示的年份
private String showMonth = ""; //用于在头部显示的月份
private String animalsYear = "";
private String leapMonth = ""; //闰哪一个月
private Set 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 getSet() {
return mSet;
}
public void setSet(Set 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;
}
}
布局文件:
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
layout="@layout/layout_public_finish_menu"
/>
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@color/bg_home_gone_menu"
android:gravity="center"
android:orientation="horizontal"
>
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"
/>
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"
/>
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"
/>
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"
/>
Item布局
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_rectangle_null_black_1">
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"
/>
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"
/>
布局只供参考...可以根据需求进行修改
下面就看看简单的调用
//传入当前的年,月..已经选中的时间(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 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实现日历的方法相关推荐
- android+高仿+日历,Android开源的精美日历控件,热插拔设计的万能自定义UI
UI框架应该逻辑与界面实现分离,该日历控件使用了热插拔的设计 ,简单几步即可实现你需要的UI效果,热插拔的思想是你提供你的实现,我提供我的插座接口,与自定义Behavior是一样的思想. 听说第一页无 ...
- android 人生日历,android版人生日历日子怎么用 安卓版人生日历日子使用教程
人生日历android版新发3.3.05.10版本,新增日子功能,那么android版人生日历日子怎么用呢?今天小编就为大家分享安卓版人生日历日子使用教程,一起来看看吧! 人生日历的日子,设计成四叶草 ...
- android谷歌补丁日期,在谷歌日历Android中添加开始日期和结束日期之间所有日期的事件...
在谷歌日历 Android中添加开始日期和结束日期之间所有日期的事件.我希望每3个月剩余一次,直到结束日期. 这是我的功能 public void addEvent1(Context ctx, Str ...
- Android SimpleAdapter显示ListView、GridView
SimpleAdapter作为一个数据集,主要向ListView.GridView容器填充数据,总结了几种填充方式,原理很简单,直接看代码和效果图 1. ListView单行显示(simple_lis ...
- android行高,android – GridView的行高
如何使行高适合GridView中最高的项目? 因为默认情况下它是失败的. 更新: 这里是网格布局 android:layout_width="fill_parent" androi ...
- java使用gridview,网格控件GridView在Android中的使用
我们在上面之前发表过一篇"使用Gallery实现缩略图浏览器",今天介绍另一种类似的控件,但是该控件是以网格的方式显示的,也就是说,当我们使用它来显示一组图片,结果图片将会以类似九 ...
- Android 可拖拽的GridView效果实现, 长按可拖拽和item实时交换
本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17718579) 在Android开发中,我们常常用到ListView ...
- Android中适用于ListView、GridView等组件的通用Adapter
今天随便逛逛CSDN,看到主页上推荐了一篇文章Android 高速开发系列 打造万能的ListView GridView 适配器,刚好这两天写项目自己也封装了相似的CommonAdapter,曾经也在 ...
- android比较常用的布局,Android_九宫图比较常用的多控件布局(GridView)使用介绍,GridView跟ListView都是比较常用的 - phpStudy...
九宫图比较常用的多控件布局(GridView)使用介绍 GridView跟ListView都是比较常用的多控件布局,而GridView更是实现九宫图的首选!本文就是介绍如何使用GridView实现九宫 ...
最新文章
- ExecuteNonQuery()返回受影响行数不适用select语句
- web开发语言大盘点
- L1-036. A乘以B
- .net ajax批量删除,asp.net 全部选中与取消操作,选中后的删除(ajax)实现无刷新效果...
- oracle存档模式,Oracle的备份和存档模式
- HttpClient api-连接池
- oracle10g-创建表空间 用户
- springsecurity 不允许session并行登录_Spring Security 实战干货:实现自定义退出登录...
- 项目功能介绍 非常有用
- win7开机突然变得很慢_几个步骤教你解决win7旗舰版开机超级慢
- 计算机设计大赛答辩提问,电子设计大赛答辩常见问题合集
- mysql显示中文乱码问题解决办法(部分情况下适用)
- 廊坊金彩教育:店铺装修怎么更吸引客户
- 2020年Vault咨询公司排名TOP 50
- Android项目解耦--路由框架ARouter的使用
- (glidejs)glidejs的使用
- 如何利用今日头条推荐规则, 打造阅读量100万+的爆款文章?
- 宝塔linux面板时区不正确怎么修改
- Tableau各版本更新情况
- ToDesk 远程桌面控制
热门文章
- 高德地图搜索结果点击事件
- Element type is invalid: expected a string (for built-in components) or a class/function (for compos
- python工作目录是什么意思_Docker的工作目录是什么意思?
- 可爱又迷人的反叛角色
- UVa 1665 岛屿 (并查集)
- 自动更换壁纸的小软件:likecan
- c语言循环中按键跳出,C语言跳出循环
- 职高计算机基础工作计划,2019职高教师个人工作计划
- pythonarp攻击_《python黑帽子》ARP缓存投毒python3写法(兼容Windows)
- react报错: Unable to preventDefault inside passive event li ……