虚位以待(AD)
虚位以待(AD)
首页 > 软件编程 > Android编程 > Android使用GridView实现日历的方法

Android使用GridView实现日历的方法
类别:Android编程   作者:码皇   来源:互联网   点击:

本篇文章主要介绍了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<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实现日历 andro