效果图:

Android Studio 自定义日历的简单实现_第1张图片

目录树

Android Studio 自定义日历的简单实现_第2张图片

1,DayBean.java用来存储每天的信息

package com.example.l_b.calendar.bean;public class DayBean {    private int day;    private int month;    private int year;    // 是否为当前月    private boolean currentMonth;    // 是否为今天    private boolean currentDay;    public int getDay() {        return day;    }    public void setDay(int day) {        this.day = day;    }    public int getMonth() {        return month;    }    public void setMonth(int month) {        this.month = month;    }    public int getYear() {        return year;    }    public void setYear(int year) {        this.year = year;    }    public boolean isCurrentMonth() {        return currentMonth;    }    public void setCurrentMonth(boolean currentMonth) {        this.currentMonth = currentMonth;    }    public boolean isCurrentDay() {        return currentDay;    }    public void setCurrentDay(boolean currentDay) {        this.currentDay = currentDay;    }}

2,自定义适配器

package com.example.l_b.calendar.adapter;import android.content.Context;import android.graphics.Color;import android.graphics.Typeface;import android.view.Gravity;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import com.example.l_b.calendar.bean.DayBean;import java.util.List;public class DayAdapter extends BaseAdapter {    private List<DayBean> list;    private Context context;    public DayAdapter(List<DayBean> list, Context context) {        this.list = list;        this.context = context;    }    @Override    public int getCount() {        return list.size();    }    @Override    public DayBean getItem(int position) {        return list.get(position);    }    @Override    public long getItemId(int position) {        return 0;    }    @Override    public View getView(int position, View view, ViewGroup parent) {        TextView textView;        // 使用缓存机制提高利用率        if (view == null) {            textView = new TextView(context);            textView.setPadding(5, 5, 5, 5);            view = textView;        } else {            textView = (TextView) view;        }        DayBean bean = getItem(position);        textView.setText(bean.getDay() + "");        textView.setGravity(Gravity.CENTER);        textView.setTextColor(Color.BLACK);        textView.setTypeface(Typeface.DEFAULT_BOLD);        if (bean.isCurrentDay()) {            textView.setBackgroundColor(Color.parseColor("#fd5f00"));            textView.setTextColor(Color.WHITE);        } else if (bean.isCurrentMonth()) {            textView.setBackgroundColor(Color.WHITE);            textView.setTextColor(Color.BLACK);        } else {            // 通过 parseColor 方法得到的颜色不可以简写,必须写满六位            textView.setBackgroundColor(Color.parseColor("#aaaaaa"));            textView.setTextColor(Color.BLACK);        }        // 返回 view 或 textView 都行,因为都是同一个对象        return textView;    }}
这个子 view 比较简单,可以自行去做成自己想要的效果

3,主布局

效果图

Android Studio 自定义日历的简单实现_第3张图片

代码

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="match_parent"    android:layout_height="match_parent">    <TextView        android:id="@+id/tvCurrentDate"        android:text="2019-6-24"        android:textSize="18sp"        android:gravity="center"        android:textStyle="bold"        android:textColor="#fff"        android:background="#fd5f00"        android:layout_width="match_parent"        android:layout_height="40dp" />    <LinearLayout        android:background="#f6f6e9"        android:layout_width="match_parent"        android:layout_height="wrap_content">        <TextView            android:id="@+id/tvPreMonth"            android:padding="5dp"            android:text="上一月"            android:layout_width="0dp"            android:textSize="16sp"            android:layout_weight="1"            android:gravity="center"            android:textStyle="bold"            android:textColor="#000"            android:layout_height="wrap_content" />        <TextView            android:layout_width="1dp"            android:background="#000"            android:layout_height="match_parent" />        <TextView            android:id="@+id/tvNextMonth"            android:text="下一月"            android:textStyle="bold"            android:textColor="#000"            android:gravity="center"            android:textSize="16sp"            android:padding="5dp"            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="wrap_content" />    LinearLayout>    <TextView        android:layout_width="match_parent"        android:background="#000"        android:layout_height="1dp" />    <LinearLayout        android:background="#000"        android:padding="1dp"        android:layout_width="match_parent"        android:layout_height="wrap_content">        <TextView            android:layout_marginRight="1dp"            android:background="#fff"            android:text="周日"            android:textStyle="bold"            android:textColor="#000"            android:gravity="center"            android:textSize="16sp"            android:padding="5dp"            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="wrap_content" />        <TextView            android:layout_marginRight="1dp"            android:background="#fff"            android:text="周一"            android:textStyle="bold"            android:textColor="#000"            android:gravity="center"            android:textSize="16sp"            android:padding="5dp"            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="wrap_content" />        <TextView            android:layout_marginRight="1dp"            android:background="#fff"            android:text="周二"            android:textStyle="bold"            android:textColor="#000"            android:gravity="center"            android:textSize="16sp"            android:padding="5dp"            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="wrap_content" />        <TextView            android:layout_marginRight="1dp"            android:background="#fff"            android:text="周三"            android:textStyle="bold"            android:textColor="#000"            android:gravity="center"            android:textSize="16sp"            android:padding="5dp"            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="wrap_content" />        <TextView            android:layout_marginRight="1dp"            android:background="#fff"            android:text="周四"            android:textStyle="bold"            android:textColor="#000"            android:gravity="center"            android:textSize="16sp"            android:padding="5dp"            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="wrap_content" />        <TextView            android:layout_marginRight="1dp"            android:background="#fff"            android:text="周五"            android:textStyle="bold"            android:textColor="#000"            android:gravity="center"            android:textSize="16sp"            android:padding="5dp"            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="wrap_content" />        <TextView            android:layout_marginRight="1dp"            android:background="#fff"            android:text="周六"            android:textStyle="bold"            android:textColor="#000"            android:gravity="center"            android:textSize="16sp"            android:padding="5dp"            android:layout_width="0dp"            android:layout_weight="1"            android:layout_height="wrap_content" />    LinearLayout>    <GridView        android:id="@+id/gv"        android:numColumns="7"        android:layout_width="match_parent"        android:layout_height="wrap_content">    GridView>LinearLayout>
tip:使用 ctrl + alt + 字母L 可以帮我们快速规范代码

4,主代码

这里使用了 LayoutCreator 插件快速绑定布局空间,非常方便,安装后按 alt + insert 键可以看到,看我其它的文章,提供了下载。
tip:插件只可以集成到 android studio ,不可以通过lib包导入到项目中,不然会无效
package com.example.l_b.calendar;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.GridView;import android.widget.TextView;import com.example.l_b.calendar.adapter.DayAdapter;import com.example.l_b.calendar.bean.DayBean;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Calendar;import java.util.Date;import java.util.List;import java.util.Locale;public class MainActivity extends AppCompatActivity {    private TextView tvCurrentDate;    private TextView tvPreMonth;    private TextView tvNextMonth;    private GridView gv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 初始化布局        initView();    }    private void initView() {        tvCurrentDate = (TextView) findViewById(R.id.tvCurrentDate);        tvPreMonth = (TextView) findViewById(R.id.tvPreMonth);        tvNextMonth = (TextView) findViewById(R.id.tvNextMonth);        gv = (GridView) findViewById(R.id.gv);        // 初始化适配器        initAdapter();    }    private void initAdapter() {        final List<DayBean> dataList = new ArrayList<>();        final DayAdapter adapter = new DayAdapter(dataList, this);        gv.setAdapter(adapter);        // 拿到日历对象,动态设置时间        // 使用日历对象可以帮我们避免一些问题,如 月数 的临界点问题,到的 12 月是再加 1 的话会自动        // 帮我们加到下一年去,同理从 1 月到 12 月也一样。        final Calendar calendar = Calendar.getInstance();        setCurrentData(calendar);        updateAdapter(calendar, dataList, adapter);        tvPreMonth.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);                updateAdapter(calendar, dataList, adapter);            }        });        tvNextMonth.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);                updateAdapter(calendar, dataList, adapter);            }        });    }    private void updateAdapter(Calendar calendar, List<DayBean> dataList, DayAdapter adapter) {        dataList.clear();        setCurrentData(calendar);        // 得到本月一号的星期索引        // 索引从 1 开始,第一个为星期日,减1是为了与星期对齐,如星期一对应索引1,星期二对应索引二        calendar.set(Calendar.DAY_OF_MONTH, 1);        int weekIndex = calendar.get(Calendar.DAY_OF_WEEK) - 1;        // 将日期设为上个月        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);        int preMonthDays = getMonth(calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.YEAR));        // 拿到上一个月的最后几天的天数        for (int i = 0; i < weekIndex; i++) {            DayBean bean = new DayBean();            bean.setYear(calendar.get(Calendar.YEAR));            bean.setMonth(calendar.get(Calendar.MONTH) + 1);            bean.setDay(preMonthDays - weekIndex + i + 1);            bean.setCurrentDay(false);            bean.setCurrentMonth(false);            dataList.add(bean);        }        // 将日期设为当月        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);        int currentDays = getMonth(calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.YEAR));        // 拿到当月的天数        for (int i = 0; i < currentDays; i++) {            DayBean bean = new DayBean();            bean.setYear(calendar.get(Calendar.YEAR));            bean.setMonth(calendar.get(Calendar.MONTH) + 1);            bean.setDay(i + 1);            // 当前日期            String nowDate = getFormatTime("yyyy-M-d", Calendar.getInstance().getTime());            // 选择的日期            String selectDate = getFormatTime("yyyy-M-", calendar.getTime()) + (i + 1);            // 假如相等的话,那么就是今天的日期了            if (nowDate.contentEquals(selectDate)) {                bean.setCurrentDay(true);            } else {                bean.setCurrentDay(false);            }            bean.setCurrentMonth(true);            dataList.add(bean);        }                // 拿到下个月第一周的天数        // 先拿到下个月第一天的星期索引        // 之前设为了1号,所以将日历对象的月数加 1 就行了        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);        weekIndex = calendar.get(Calendar.DAY_OF_WEEK) - 1;        for (int i = 0; i < 7 - weekIndex; i++) {            DayBean bean = new DayBean();            bean.setYear(calendar.get(Calendar.YEAR));            bean.setMonth(calendar.get(Calendar.MONTH) + 1);            bean.setDay(i + 1);            bean.setCurrentDay(false);            bean.setCurrentMonth(false);            dataList.add(bean);        }        adapter.notifyDataSetChanged();        // 最后将日期设为当月        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1);    }    // 设置当前的时间    private void setCurrentData(Calendar calendar) {        tvCurrentDate.setText(calendar.get(Calendar.YEAR) + "年" + (calendar.get(Calendar.MONTH) + 1) + "月");    }    // 判断是否为闰年    public boolean isRunYear(int y) {        return y % 4 == 0 && y % 100 != 0 || y % 400 == 0;    }    // 格式化时间,设置时间很方便,也比较简单,学的很快    public static String getFormatTime(String p, Date t) {        return new SimpleDateFormat(p, Locale.CHINESE).format(t);    }    // 传入年和月得出当月的天数    public int getMonth(int m, int y) {        switch (m) {            case 2:                return isRunYear(y) ? 29 : 28;            case 4:            case 6:            case 9:            case 11:                return 30;            default:                return 31;        }    }}
最后大功告成,有问题可以问,看到会回复!

更多相关文章

  1. Android 日历控件WeekCalendar
  2. Android 计算出生日期至今天数(获取宝宝出生到现在天数)
  3. Android中日期时间格式转换
  4. android 时间,日期对话框
  5. Android 日历方式显示的日期选择组件(日历控件之一)
  6. Android中Calendar与Date的区别以及消除时区对日期操作影响的方

随机推荐

  1. Android——Intent在Activity的使用详解-
  2. Glide源码解析篇之框架主体结构(一)
  3. 00003 不思议迷宫.0011.2:Android新版中的
  4. [置顶] 基于Proxy思想的Android插件框架
  5. Android同时按下多个按钮
  6. 第21章 0113-jQuery常用DOM操作与Ajax,学
  7. Android数据库更新onupgrade
  8. Android的联通性---USB主机模式(二)
  9. Android补间动画详情
  10. SDL 从内存流中加载图像并显示