自定义一个日历

刚开始做android的时候,遇到日历根本无法下手,加上经验不足,花了很长时间去修改别人写的日历。一个偶然的机会,现在的项目需要日历,我再也无法容忍了,因为日历样式很复杂,所以本人决定自己写一个日历。下面来说说日历最重要的东西。

首先,一年12个月中有哪些是大月哪些是小月。还有个2月痕特别。处理方法如下:

private void setSmallMonth(List<String> list) {
    for(int i=0;i<30;i++){
        list.add((i+1)+"");
    }
}

private void setBigMonth(List<String> list) {
    for(int i=0;i<31;i++){
        list.add((i+1)+"");
    }
}

private void set2Month(List<String> list,int currentYear) {
    if(currentYear%4==0){
        for(int i=0;i<29;i++){
            list.add((i+1)+"");
        }
    }else{
        for(int i=0;i<28;i++){
            list.add((i+1)+"");
        }

    }
}

其次,知道当前月的第一天是周几:
Calendar instance = Calendar.getInstance();

instance.set(Calendar.DAY_OF_MONTH, 1);
dayOfWeekInMonth = instance.get(Calendar.DAY_OF_WEEK);

再来就是当前日期了:

currentYear = instance.get(Calendar.YEAR);
currentShowYear=currentYear;
currentMonth = instance.get(Calendar.MONTH);
currentMonth=currentMonth+1;
realCurrentMonth=currentMonth;
dayOfMonth = instance.get(Calendar.DAY_OF_MONTH);
有了这些数据,基本就可以自定义一个简单的日历了 。


我这里是用的GrideView布局,根据每月天数,GrideView的格子数是固定的42个,根据当月第一天是周几可以判定从日期第几个格子开始
放置。根据当前日期我们可以把当前日期设置为特定的颜色等等
我这里是把日历封装成了一个dialog
package com.achievo.haoqiu.widget.view;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.TextView;

import com.achievo.haoqiu.R;
import com.achievo.haoqiu.activity.adapter.BottomDateCalendarAdapter;
import com.achievo.haoqiu.util.ScreenUtils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * Created by 石志华 on 2016/3/3.
 */
public class BottomDateDialog extends Dialog{

    public BottomDateDialog(Context context) {
        super(context);
    }

    public static class Builder implements View.OnClickListener, AdapterView.OnItemClickListener {
        private Activity context;
        private BottomDialog dialog;
        private int currentMonth;//记录当前显示的是哪个月份
        private BottomDateCalendarAdapter calendarAdapter;
        private int dayOfMonth;
        private int dayOfWeekInMonth;
        private TextView tv_title;
        private List<String> list;
        private int currentYear;//当前真实年份
        private int realCurrentMonth;//记录当前真实月份
        private boolean isBeforeCurrentMonth=true;
        private boolean isCurrentMonth=true;
        private OnDialogClick onDialogClick;
        private String selectedDate="";
        private int currentShowYear;

        public Builder(Activity context,String selectedDate) {
            this.context = context;
            this.selectedDate=selectedDate;
        }

        public BottomDialog create() {
            BottomDialog.Builder builder = new BottomDialog.Builder(context);
            View inflate = View.inflate(context, R.layout.bottom_date_dialog, null);
            View tv_cancel = inflate.findViewById(R.id.tv_cancel);
            View iv_left = inflate.findViewById(R.id.iv_left);
            View iv_right = inflate.findViewById(R.id.iv_right);
            tv_title = (TextView) inflate.findViewById(R.id.tv_title);
            GridView grideView = (GridView) inflate.findViewById(R.id.gridView);
            grideView.setOnItemClickListener(this);
            //获取当前日期
            Calendar instance = Calendar.getInstance();
            currentYear = instance.get(Calendar.YEAR);
            currentShowYear=currentYear;
            currentMonth = instance.get(Calendar.MONTH);
            currentMonth=currentMonth+1;
            realCurrentMonth=currentMonth;
            dayOfMonth = instance.get(Calendar.DAY_OF_MONTH);

            //设置选中日期
            if(selectedDate==null||"".equals(selectedDate)){
                isCurrentMonth=true;
            }else{
                String[] split = selectedDate.split("-");
                if(currentYear==Integer.valueOf(split[0]) && currentMonth==Integer.valueOf(split[1])){
                    isCurrentMonth=true;
                }else{
                    isCurrentMonth=false;
                }

                currentYear=Integer.valueOf(split[0]);
                currentMonth = Integer.valueOf(split[1]);
                instance.set(Calendar.YEAR,Integer.valueOf(split[0]));
                instance.set(Calendar.MONTH,Integer.valueOf(split[1])-1);
            }
            //获取当月第一天是周几
            instance.set(Calendar.DAY_OF_MONTH, 1);
            dayOfWeekInMonth = instance.get(Calendar.DAY_OF_WEEK);
            tv_title.setText(currentYear + context.getResources().getString(R.string.text_year) + currentMonth + context.getResources().getString(R.string.text_month));

            list = new ArrayList<>();
            setDays(currentYear,currentMonth);
            calendarAdapter = new BottomDateCalendarAdapter(context,list,dayOfWeekInMonth,dayOfMonth,isBeforeCurrentMonth,isCurrentMonth);
            String[] split = selectedDate.split("-");
            if(Integer.valueOf(split[0])==currentYear && Integer.valueOf(split[1])==currentMonth){
                calendarAdapter.setSelectedDay(Integer.valueOf(split[2]));
            }else{
                calendarAdapter.setSelectedDay(0);
            }
            grideView.setAdapter(calendarAdapter);

            tv_cancel.setOnClickListener(this);
            iv_left.setOnClickListener(this);
            iv_right.setOnClickListener(this);

            dialog = builder.create();
            Window window = dialog.getWindow();
            WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
            lp.width = ScreenUtils.getScreenWidth(context);
            dialog.getWindow().setAttributes(lp);
            dialog.getWindow().setWindowAnimations(R.style.AnimationPreview);
            window.setGravity(Gravity.BOTTOM);
            dialog.setContentView(inflate);
            return dialog;
        }

        public void setOnDialogClick(OnDialogClick onDialogClick){
            this.onDialogClick=onDialogClick;
        }

        @NonNull
        private void setDays(int currentYear,int currentMonth) {
            list.clear();
            if(currentMonth ==1|| currentMonth ==3|| currentMonth ==5|| currentMonth ==7|| currentMonth ==8|| currentMonth ==10|| currentMonth ==12){
                setBigMonth(list);
            }else if(currentMonth ==2){
                set2Month(list, currentYear);
            }else{
                setSmallMonth(list);
            }
        }


        private void setSmallMonth(List<String> list) {
            for(int i=0;i<30;i++){
                list.add((i+1)+"");
            }
        }

        private void setBigMonth(List<String> list) {
            for(int i=0;i<31;i++){
                list.add((i+1)+"");
            }
        }

        private void set2Month(List<String> list,int currentYear) {
            if(currentYear%4==0){
                for(int i=0;i<29;i++){
                    list.add((i+1)+"");
                }
            }else{
                for(int i=0;i<28;i++){
                    list.add((i+1)+"");
                }

            }
        }

        @Override
        public void onClick(View v) {
            int year=0;
            switch (v.getId()){
                case R.id.tv_cancel:
                    dialog.dismiss();
                    break;
                case R.id.iv_left:
                    year = setDate(-1,currentShowYear);
                    setDays(year,currentMonth);
                    tv_title.setText(year + context.getResources().getString(R.string.text_year) + currentMonth + context.getResources().getString(R.string.text_month));
                    calendarAdapter.notifyDataSetChanged();
                    break;
                case R.id.iv_right:
                    year = setDate(1,currentShowYear);
                    setDays(year,currentMonth);
                    tv_title.setText(year + context.getResources().getString(R.string.text_year) + currentMonth + context.getResources().getString(R.string.text_month));
                    calendarAdapter.notifyDataSetChanged();
                    break;

            }
        }


        public int setDate(int addOrDown,int year){
            Calendar instance = Calendar.getInstance();
            currentMonth = currentMonth+addOrDown;
            if(currentMonth>12){
                instance.set(Calendar.YEAR,year+1);
                instance.set(Calendar.MONTH,0);
                currentMonth=1;
            }else if(currentMonth<1){
                instance.set(Calendar.YEAR,year-1);
                instance.set(Calendar.MONTH,11);
                currentMonth=12;
            }else{
                instance.set(Calendar.YEAR,year);
                instance.set(Calendar.MONTH,currentMonth-1);
            }

            //当前显示年份在真是年份之后
            if(instance.get(Calendar.YEAR)>currentYear){
                isBeforeCurrentMonth=false;
                isCurrentMonth=false;
                //当前显示年份就是真实年份
            }else if(instance.get(Calendar.YEAR)==currentYear){
                if(currentMonth>realCurrentMonth){
                    isBeforeCurrentMonth=false;
                    isCurrentMonth=false;
                }else if(currentMonth==realCurrentMonth){
                    isBeforeCurrentMonth=true;
                    isCurrentMonth=true;
                }else{
                    isBeforeCurrentMonth=true;
                    isCurrentMonth=false;
                }
                //当前显示年份在真实年份之前
            }else{
                isBeforeCurrentMonth=true;
                isCurrentMonth=false;
            }

            calendarAdapter.setIsCurrentMonth(isCurrentMonth);
            calendarAdapter.setIsBeforeCurrentMonth(isBeforeCurrentMonth);

            //获取当月第一天周几
            instance.set(Calendar.DAY_OF_MONTH, 1);
            dayOfWeekInMonth=instance.get(Calendar.DAY_OF_WEEK);
            calendarAdapter.setDayOfWeek(dayOfWeekInMonth);

            String[] split = selectedDate.split("-");
            if(Integer.valueOf(split[0])==instance.get(Calendar.YEAR) && Integer.valueOf(split[1])==currentMonth){
                calendarAdapter.setSelectedDay(Integer.valueOf(split[2]));
            }else{
                calendarAdapter.setSelectedDay(0);
            }

            currentShowYear=instance.get(Calendar.YEAR);
            return currentShowYear;
        }

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            TextView tv_day = (TextView) view.findViewById(R.id.tv_day);
            if((tv_day.getCurrentTextColor()==context.getResources().getColor(R.color.font_333333)||tv_day.getCurrentTextColor()==context.getResources().getColor(R.color.white))||
                    tv_day.getCurrentTextColor()==context.getResources().getColor(R.color.blue_55c0ea)){
                if(position>=dayOfWeekInMonth-1){
                    String trim = tv_title.getText().toString().trim();
                    if(trim.length()==7){//单月
                        //月份和日必须是两位数
                        if(list.get(position-(dayOfWeekInMonth-1)).length()==1){
                            selectedDate=trim.substring(0,4)+"-0"+trim.substring(5,6)+"-0"+list.get(position-(dayOfWeekInMonth-1));
                        }else{
                            selectedDate=trim.substring(0,4)+"-0"+trim.substring(5,6)+"-"+list.get(position-(dayOfWeekInMonth-1));
                        }
                    }else if(trim.length()==8){//双月
                        if(list.get(position - (dayOfWeekInMonth-1)).length()==1){
                            selectedDate=trim.substring(0,4)+"-"+trim.substring(5,7)+"-0"+list.get(position - (dayOfWeekInMonth-1));
                        }else{
                            selectedDate=trim.substring(0,4)+"-"+trim.substring(5,7)+"-"+list.get(position - (dayOfWeekInMonth-1));
                        }
                    }

                    calendarAdapter.setSelectedDay(Integer.valueOf(list.get(position - (dayOfWeekInMonth - 1))));
                    calendarAdapter.notifyDataSetChanged();
                    if(onDialogClick!=null){
                        onDialogClick.onClick(selectedDate);
                    }

                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            dialog.dismiss();
                        }
                    },300);
                }else{
                    return;
                }
            }
        }


        public interface OnDialogClick{
            void onClick(String date);
        }
    }
}


示例下载地址 http://download.csdn.net/detail/qq_26491053/9525462 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值