本文实例为大家分享了Android Studio自定义日历的具体代码,供大家参考,具体内容如下
效果图:
目录树
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.主布局
效果图
代码
<?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.主代码
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;
}
}
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。