本文实例为大家分享了Android自定义实现日历控件的具体代码,供大家参考,具体内容如下
1. Calendar类
2. 布局
创建calendar_layout.xml
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:padding="20sp"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <RelativeLayout
- android:id="@+id/titleRl"
- android:layout_width="match_parent"
- android:layout_height="30dp">
- <TextView
- android:id="@+id/lastTv"
- android:text="上一月"
- android:layout_alignParentLeft="true"
- android:gravity="center"
- android:layout_width="wrap_content"
- android:layout_height="30dp"></TextView>
- <TextView
- android:id="@+id/monthTv"
- android:text="十一月"
- android:gravity="center"
- android:layout_centerHorizontal="true"
- android:layout_width="wrap_content"
- android:layout_height="30dp"></TextView>
- <TextView
- android:id="@+id/nextTv"
- android:text="下一月"
- android:gravity="center"
- android:layout_alignParentRight="true"
- android:layout_width="wrap_content"
- android:layout_height="30dp"></TextView>
- </RelativeLayout>
- <LinearLayout
- android:id="@+id/weekLl"
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <TextView
- android:id="@+id/Tv7"
- android:text="日"
- android:gravity="center"
- android:layout_weight="1"
- android:layout_width="0dp"
- android:layout_height="30dp"></TextView>
- <TextView
- android:id="@+id/Tv1"
- android:text="一"
- android:gravity="center"
- android:layout_weight="1"
- android:layout_width="0dp"
- android:layout_height="30dp"></TextView>
- <TextView
- android:id="@+id/Tv2"
- android:text="二"
- android:gravity="center"
- android:layout_weight="1"
- android:layout_width="0dp"
- android:layout_height="30dp"></TextView>
- <TextView
- android:id="@+id/Tv3"
- android:text="三"
- android:gravity="center"
- android:layout_weight="1"
- android:layout_width="0dp"
- android:layout_height="30dp"></TextView>
- <TextView
- android:id="@+id/Tv4"
- android:text="四"
- android:gravity="center"
- android:layout_weight="1"
- android:layout_width="0dp"
- android:layout_height="30dp"></TextView>
- <TextView
- android:id="@+id/Tv5"
- android:text="五"
- android:gravity="center"
- android:layout_weight="1"
- android:layout_width="0dp"
- android:layout_height="30dp"></TextView>
- <TextView
- android:id="@+id/Tv6"
- android:text="六"
- android:gravity="center"
- android:layout_weight="1"
- android:layout_width="0dp"
- android:layout_height="30dp"></TextView>
- </LinearLayout>
- <GridView
- android:id="@+id/calendarCv"
- android:numColumns="7"
- android:layout_width="match_parent"
- android:layout_height="match_parent"></GridView>
- </LinearLayout>
创建item_layout.xml
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <TextView
- android:id="@+id/itemTv"
- android:gravity="center"
- android:layout_width="match_parent"
- android:layout_height="match_parent"></TextView>
- </LinearLayout>
在activity_main.xml中
- <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity">
- <com.aye.newcalendar.NewCalendar
- android:id="@+id/calendarNc"
- android:gravity="center"
- android:layout_width="match_parent"
- android:layout_height="match_parent"></com.aye.newcalendar.NewCalendar>
- </androidx.constraintlayout.widget.ConstraintLayout>
3. 业务处理
创建NewCalendar类,继承LinearLayout
- public class NewCalendar extends LinearLayout {
- private TextView lastTv,nextTv,dateTv;
- private GridView calendarGv;
-
- private Calendar calendar=Calendar.getInstance(); //日历控件初始化
- //重写三个构造方法
- public NewCalendar(Context context) {
- super(context);
- }
- public NewCalendar(Context context, @Nullable AttributeSet attrs) {
- super(context, attrs);
- initControl(context); //绑定控件
- }
- public NewCalendar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- initControl(context); //绑定控件
- }
- private void initControl(Context context){
- bindControl(context); //绑定控件
- bindControlEvent(); //绑定控件事件
- }
-
- //绑定控件事件方法
- private void bindControlEvent() {
- renderCalendar();
- //“下一月”点击事件
- nextTv.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- calendar.add(Calendar.MONTH,+1); //月份+1
- renderCalendar();
- }
- });
- //“上一个”点击事件
- lastTv.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- calendar.add(Calendar.MONTH,-1); //月份-1
- renderCalendar();
- }
- });
- }
-
- private void renderCalendar() {
- SimpleDateFormat sdf = new SimpleDateFormat("MMM yyy"); //日期格式化
- dateTv.setText(sdf.format(calendar.getTime())); //设置月份
- ArrayList<Date> cells = new ArrayList<>();
- Calendar calendar1 = (Calendar) calendar.clone(); //克隆日历对象
- calendar1.set(Calendar.DAY_OF_MONTH, 1); //置于当月第一天;
- int prevDays = calendar1.get(Calendar.DAY_OF_WEEK) - 1; //获取上个月最后一天是星期几
- calendar1.add(Calendar.DAY_OF_MONTH, -prevDays); //第一天
-
- int maxCount = 6 * 7; //设置每个月最大天数
- //循环存入集合中
- while (cells.size() < maxCount) {
- cells.add(calendar1.getTime());
- calendar1.add(Calendar.DAY_OF_MONTH, 1); //日期+1
- }
- //设置适配器
- calendarGv.setAdapter(new CalendarAdapter(getContext(),cells));
- }
-
-
- //适配器
- private class CalendarAdapter extends ArrayAdapter<Date>{
- LayoutInflater layoutInflater;
- public CalendarAdapter(@NonNull Context context,ArrayList<Date> days) {
- super(context, R.layout.item_layout,days);
- layoutInflater=LayoutInflater.from(context);
- }
- @NonNull
- @Override
- public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
- Date date=getItem(position);
- ViewHolder viewHolder;
- if (convertView==null){ //初始化绑定
- convertView=layoutInflater.inflate(R.layout.item_layout,parent,false);
- viewHolder=new ViewHolder();
- viewHolder.itemTv=convertView.findViewById(R.id.itemTv);
- convertView.setTag(viewHolder);
- }
- viewHolder= (ViewHolder) convertView.getTag();
- int day=date.getDate();
- viewHolder.itemTv.setText(String.valueOf(day)); //赋值
-
- return convertView;
- }
- class ViewHolder{
- TextView itemTv;
- }
- }
- private void bindControl(Context context) {
- LayoutInflater inflater=LayoutInflater.from(context);
- inflater.inflate(R.layout.calendar_layout,this);
-
- lastTv=findViewById(R.id.lastTv);
- nextTv=findViewById(R.id.nextTv);
- dateTv=findViewById(R.id.dateTv);
- calendarGv=findViewById(R.id.calendarGv);
- }
- }
3. 定制UI
在适配器getView()方法中,个性化日历界面
- Date now=new Date();
- Boolean isTheSameMonth=false; //是否与当前月份相同
- //判断显示的日期月份与当前月份相同
- if (date.getMonth()==now.getMonth()) { //月份相同
- isTheSameMonth = true;
- }
- //若显示的日期月份与当前月份相同,则设置字体颜色是黑色
- if (isTheSameMonth) {
- viewHolder.itemTv.setTextColor(Color.parseColor("#000000"));
- }
- //设置当前日期字体为红色
- if (now.getDate()==date.getDate()&&now.getMonth()==date.getMonth()&&now.getYear()==date.getYear()){
- viewHolder.itemTv.setTextColor(Color.parseColor("#ff0000"));
- }
4. 事件监听
在NewCalendar中,首先编写长按事件的接口,然后设置适配器点击事件
- //长按事件接口
- public interface NewCalendarListener{
- void onItemClick(Date date);
- }
-
- //适配器长按事件
- calendarGv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
- @Override
- public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
- if (listener==null){
- return false;
- }else {
- //获取长按的位置,传入onItemClick方法中
- listener.onItemClick((Date) parent.getItemAtPosition(position));
- return true;
- }
- }
- });
在MainActivity中,实现长按事件接口并重写方法,实现长按某个日期弹出Toast显示当前长按日期。
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- NewCalendar calendar=findViewById(R.id.calendarNc);
- calendar.listener=this;
- }
- //MainActivity实现长按事件接口
- @Override
- public void onItemClick(Date date) {
- DateFormat df= SimpleDateFormat.getDateInstance();
- Toast.makeText(this,df.format(date),Toast.LENGTH_SHORT).show();
- }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。