Android 自定義日期段選擇控件,開始日期-結束日期。

開發中碰到個需求,需要在一個控件中選擇完成開始和結束日期。實現的過程走的是程序員開發的老路子,找到輪子後自己改吧改吧就成了。去年做的找不到參考的文章連接了,請原博主見諒。

當時做的時候有幾個需求:1.當天爲最大的結束日期,2.最大選擇範圍1年,3.開始時間和結束時間可以爲同一天。如有其他需求實現,可以參考代碼改進一下。先上效果圖:

視頻點擊後的虛影是屏幕錄製的原因。實現步驟:(如有缺失什麼資源,請告知。開始時間和結束時間顯示自己佈局內添加就可以)

1.自定義控件屬性

<declare-styleable name="MyCalendar">
        <attr name="dateformat" format="string"></attr>
        <attr name="titleSize" format="dimension"></attr>
        <attr name="titleColor" format="color"></attr>
        <attr name="goIcon" format="reference"></attr>
        <attr name="preIcon" format="reference"></attr>
        <attr name="dayInMonthColor" format="color"></attr>
        <attr name="dayOutMonthcolor" format="color"></attr>
        <attr name="todayColor" format="color"></attr>
        <attr name="todayEmptycircleColor" format="color"></attr>
        <attr name="todayFillcircleColor" format="color"></attr>
        <attr name="calendarbackground" format="color|reference"></attr>
</declare-styleable>

2.自定義控件代碼

/**
 * @Description: 可以選擇時間範圍的日曆控件
 * @Author MengXY
 * @Emil [email protected]
 * @Date 2019/1/8
*/
public class CalendarView extends LinearLayout  implements View.OnClickListener{
    private TextView title;
    private RecyclerView recyclerView;
    private RelativeLayout layout_calendar_gonext;
    private RelativeLayout layout_calendar_goup;
    private LinearLayoutManager linearLayoutManager;

    private Calendar curDate = Calendar.getInstance();
    //從服務器獲取的日期
    private Date dateFromServer;

    //外層主recyclerview的adapter
    private MainRvAdapter mainAdapter;
    private List<CalendarCell> months = new ArrayList<>();
    private Context context;

    //相關屬性
    private int titleColor;
    private int titleSize;

    private int enableSelectColor;
    private int disableSeletColor;
    private int todayColor;
    private int todayEmptyColor;
    private int todayFillColor;

    /** 初始日期爲當前日期前一年*/
    private String time;
    private long timeBefor;
    private long timeNow;

    private List<String> titles = new ArrayList<>();

    //點擊的開始時間與結束時間
    private Date sDateTime;
    private Date eDateTime;
    private boolean isSelectingSTime = true;

    private HashMap<Integer, SubRvAdapter> allAdapters = new HashMap<>();


    public CalendarView(Context context) {
        this(context, null);
    }

    public CalendarView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    private int maxSelect = 13;

    public CalendarView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MyCalendar);
        titleColor = ta.getColor(R.styleable.MyCalendar_titleColor, Color.WHITE);
        titleSize = (int) ta.getDimension(R.styleable.MyCalendar_titleSize, 15);
        enableSelectColor = ta.getColor(R.styleable.MyCalendar_dayInMonthColor, context.getResources().getColor(R.color.text_lable));
        disableSeletColor = ta.getColor(R.styleable.MyCalendar_dayOutMonthcolor, context.getResources().getColor(R.color.text_unenable));
        todayColor = ta.getColor(R.styleable.MyCalendar_todayColor, Color.BLUE);
        todayEmptyColor = ta.getColor(R.styleable.MyCalendar_todayEmptycircleColor, Color.CYAN);
        todayFillColor = ta.getColor(R.styleable.MyCalendar_todayFillcircleColor, Color.CYAN);
        ta.recycle();
        this.context = context;
        init(context);
    }
    //該方法用於設置從服務器獲取的時間,如果沒有從服務器獲取的時間將使用手機本地時間
    private void initTime() {
        Calendar calendar = Calendar.getInstance(); //得到日曆
        calendar.setTime(new Date());
        calendar.add(Calendar.MONTH,-(maxSelect-1));
        time = DateUtils.formatData(calendar.getTime(),Constant.TFORMATE_YMD);
        timeBefor = DateUtils.getDataTime(time);
        String now = DateUtils.formatData(new Date(),Constant.TFORMATE_YMD);
        timeNow = DateUtils.getDataTime(now);
//        LogUtils.e("之前日期:"+time+"=="+timeBefor);
//        LogUtils.e("當前日期:"+now+"=="+timeNow);

        curDate = DateUtil.strToCalendar(time, Constant.TFORMATE_YMD);
        dateFromServer = DateUtil.strToDate(time, Constant.TFORMATE_YMD);
    }

    private void init(Context context) {
        bindView(context);
        renderCalendar();
    }


    private void bindView(Context context) {
        View view = LayoutInflater.from(context).inflate(R.layout.appoint_calendarview, this, false);
        title = (TextView) view.findViewById(R.id.calendar_title);
        title.setTextColor(titleColor);
        title.setTextSize(titleSize);
        layout_calendar_gonext = view.findViewById(R.id.layout_calendar_gonext);
        layout_calendar_goup = view.findViewById(R.id.layout_calendar_goup);
        layout_calendar_gonext.setOnClickListener(this);
        layout_calendar_goup.setOnClickListener(this);
        recyclerView = (RecyclerView) view.findViewById(R.id.calendar_rv);
        linearLayoutManager = new LinearLayoutManager(this.context, LinearLayoutManager.HORIZONTAL, false);
        recyclerView.setLayoutManager(linearLayoutManager);
        PagerSnapHelper snapHelper = new PagerSnapHelper();
        snapHelper.attachToRecyclerView(recyclerView);
        addView(view);
    }

    public void renderCalendar() {
        months.clear();
        initTime();
        for (int i = 0; i < maxSelect; i++) {
            ArrayList<Date> cells = new ArrayList<>();
            if (i != 0) {
                curDate.add(Calendar.MONTH, 1);//後推一個月
            } else {
                curDate.add(Calendar.MONTH, 0);//當前月
            }
            Calendar calendar = (Calendar) curDate.clone();
            //將日曆設置到當月第一天
            calendar.set(Calendar.DAY_OF_MONTH, 1);
            //獲得當月第一天是星期幾,如果是星期一則返回1此時1-1=0證明上個月沒有多餘天數
            int prevDays = calendar.get(Calendar.DAY_OF_WEEK) - 1;
            //將calendar在1號的基礎上向前推prevdays天。
            calendar.add(Calendar.DAY_OF_MONTH, -prevDays);
            //最大行數是6*7也就是,1號正好是星期六時的情況
            int maxCellcount = 6 * 7;
            while (cells.size() < maxCellcount) {
                cells.add(calendar.getTime());
                //日期後移一天
                calendar.add(calendar.DAY_OF_MONTH, 1);
            }
            months.add(new CalendarCell(i, cells));
        }
        for (int i = 0; i < months.size(); i++) {
            //title格式 2018年6月3日
            String title = (months.get(i).getCells().get(20).getYear() + 1900) +
                    "\t-\t" +
                    (months.get(i).getCells().get(20).getMonth() + 1);
            titles.add(title);
        }
        title.setText(titles.get(maxSelect-1));
        //只限定3個月,因此模擬給3個數值即可
        mainAdapter = new MainRvAdapter(R.layout.appoint_calendarview_item, months);
        recyclerView.setAdapter(mainAdapter);
        //recyclerview 的滾動監聽
        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                title.setText(titles.get(linearLayoutManager.findLastVisibleItemPosition()));
                super.onScrollStateChanged(recyclerView, newState);
            }
        });
        recyclerView.scrollToPosition(maxSelect-1);
    }

    @Override
    public void onClick(View v) {
        int index = linearLayoutManager.findLastVisibleItemPosition();
        LogUtils.e("當前項"+index);
        switch (v.getId()){
            case R.id.layout_calendar_gonext:
                if(index < maxSelect-1){
                    recyclerView.scrollToPosition(index+1);
                    title.setText(titles.get(index+1));
                }
                break;
            case R.id.layout_calendar_goup:
                if(index > 0){
                    recyclerView.scrollToPosition(index-1);
                    title.setText(titles.get(index-1));
                }
                break;
        }

    }

    /**
     * 最外層水平recyclerview的adapter
     */
    private class MainRvAdapter extends BaseQuickAdapter<CalendarCell, BaseViewHolder> {

        public MainRvAdapter(int layoutResId, @Nullable List<CalendarCell> data) {
            super(layoutResId, data);
        }

        @Override
        protected void convert(BaseViewHolder helper, final CalendarCell item) {
            if (((RecyclerView) helper.getView(R.id.appoint_calendarview_item_rv)).getLayoutManager() == null) {
                //RecyclerView不能都使用同一個LayoutManager
                GridLayoutManager manager = new GridLayoutManager(mContext, 7);
                //recyclerview嵌套高度不固定(wrap_content)時必須setAutoMeasureEnabled(true),否則測量時控件高度爲0
                manager.setAutoMeasureEnabled(true);
                ((RecyclerView) helper.getView(R.id.appoint_calendarview_item_rv)).setLayoutManager(manager);
            }
            SubRvAdapter subRvAdapter = null;
            if (allAdapters.get(helper.getPosition()) == null) {
                subRvAdapter = new SubRvAdapter(R.layout.calendar_text_day, item.getCells());
                allAdapters.put(helper.getPosition(), subRvAdapter);
                ((RecyclerView) helper.getView(R.id.appoint_calendarview_item_rv)).setAdapter(subRvAdapter);
            } else {
                subRvAdapter = allAdapters.get(helper.getPosition());
                ((RecyclerView) helper.getView(R.id.appoint_calendarview_item_rv)).setAdapter(subRvAdapter);
            }
            //item 點擊事件響應
            subRvAdapter.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                    Date date = item.getCells().get(position);
                    if(date.getTime() >= timeBefor && date.getTime()<= timeNow ){
                        if (isSelectingSTime) {
                            //正在選擇開始時間
                            selectSDate(item.getCells().get(position));
                        } else {
                            //正在選擇結束時間
                            selectEDate(item.getCells().get(position));
                        }
                    }
                    //更新所有的adapter,比如今天6月,需要更新6、7、8三個月份不同adapter
                    Iterator iterator = allAdapters.entrySet().iterator();
                    while (iterator.hasNext()) {
                        Map.Entry entry = (Map.Entry) iterator.next();
                        ((SubRvAdapter) entry.getValue()).notifyDataSetChanged();
                    }
                }
            });
        }
    }

    public void selectSDate(Date date) {
        if (sDateTime != null && eDateTime != null) {
            sDateTime = date;
            notifyDateSelectChanged();
        } else {
            sDateTime = date;
            notifyDateSelectChanged();
        }
        eDateTime = null;
        isSelectingSTime = false;
        /** 當前沒有選擇結束時間*/
        if(this.calendaSelListener != null){
            calendaSelListener.selectStatus(false);
        }
    }

    public void selectEDate(Date date) {
        if (sDateTime != null) {
            if (date.getTime() >= sDateTime.getTime()) {
                eDateTime = date;
                isSelectingSTime = true;
                notifyDateSelectChanged();
            }else {
                eDateTime = sDateTime;
                sDateTime = date;
                isSelectingSTime = true;
                notifyDateSelectChanged();
            }
            /** 選擇完成*/
            if(this.calendaSelListener != null){
                calendaSelListener.selectStatus(true);
            }
        }

    }

    /**
     * 通知開始時間跟結束時間均改變
     */
    public void notifyDateSelectChanged() {
        if (mETimeSelectListener != null && eDateTime != null) {
            mETimeSelectListener.onETimeSelect(eDateTime);
        }
        if (mSTimeSelectListener != null && sDateTime != null) {
            mSTimeSelectListener.onSTimeSelect(sDateTime);
        }
    }


    private class SubRvAdapter extends BaseQuickAdapter<Date, BaseViewHolder> {

        public SubRvAdapter(int layoutResId, @Nullable List<Date> data) {
            super(layoutResId, data);
        }

        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
        @Override
        protected void convert(BaseViewHolder helper, Date date) {
            helper.setIsRecyclable(false);//不讓recyclerview進行復用,複用會出問題
            ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).setEmptyColor(todayEmptyColor);
            ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).setFillColor(todayFillColor);
            int day = date.getDate();
            //設置文本
            ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).setText(String.valueOf(day));
            //設置顏色
            if(date.getTime() >= timeBefor && date.getTime()<= timeNow ){
                ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).setTextColor(enableSelectColor);
            }else {
                ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).setTextColor(disableSeletColor);
            }

            //更改選中文字顏色
            if(sDateTime != null && eDateTime != null){
                if(date.getTime()>sDateTime.getTime() && date.getTime()<eDateTime.getTime()){
                    ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).isSelected(true);
                    helper.getView(R.id.calendar_day_rl).setBackgroundColor(getResources().getColor(R.color.date_duration_bg));
                }
            }
            /****************************/
            if (eDateTime != null && date.getTime() == eDateTime.getTime()) {
                //結束時間
                if(eDateTime.equals(sDateTime)){
                    ((CalendarDayRelativeLayout) helper.getView(R.id.calendar_day_rl)).isSameDay();
                }else {
                    ((CalendarDayRelativeLayout) helper.getView(R.id.calendar_day_rl)).isETime(true);
                }
                ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).isETime(true);

            }
            if (sDateTime != null && date.getTime() == sDateTime.getTime()) {
                //開始時間
                if (eDateTime != null) {
                    if(eDateTime.equals(sDateTime)) {
                        ((CalendarDayRelativeLayout) helper.getView(R.id.calendar_day_rl)).isSameDay();
                    }else {
                        ((CalendarDayRelativeLayout) helper.getView(R.id.calendar_day_rl)).isSTime(true);
                    }
                    ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).isSTime(true);
                } else {
                    ((CalendarDayRelativeLayout) helper.getView(R.id.calendar_day_rl)).isDurationSun(true);
                    ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).isSTime(true);
                }
            }

            /*****************************************/
            if(date.getTime() == timeNow){
                ((CalendarDayTextView) helper.getView(R.id.calendar_day_tv)).setToday(true);
            }
        }
    }

    private class CalendarCell {
        private int position;
        ArrayList<Date> cells;

        public CalendarCell(int position, ArrayList<Date> cells) {
            this.position = position;
            this.cells = cells;
        }

        public int getPosition() {
            return position;
        }

        public void setPosition(int position) {
            this.position = position;
        }

        public ArrayList<Date> getCells() {
            return cells;
        }

        public void setCells(ArrayList<Date> cells) {
            this.cells = cells;
        }
    }


    //開始時間的選擇監聽
    public interface CalendarSTimeSelListener {
        void onSTimeSelect(Date date);
    }

    private CalendarSTimeSelListener mSTimeSelectListener;

    public void setSTimeSelListener(CalendarSTimeSelListener li) {
        mSTimeSelectListener = li;
    }

    //結束時間的監聽事件
    public interface CalendatEtimSelListener {
        void onETimeSelect(Date date);
    }



    private CalendaSelListener calendaSelListener;

    /**選擇日期完整性*/
    public interface CalendaSelListener{
        void selectStatus(boolean isOk);
    }

    public void setCalendaSelListener(CalendaSelListener calendaSelListener) {
        this.calendaSelListener = calendaSelListener;
    }

    private CalendatEtimSelListener mETimeSelectListener;

    public void setETimeSelListener(CalendatEtimSelListener li) {
        mETimeSelectListener = li;
    }

}

3.自定義view用到的佈局 appoint_calendarview.xml,對應日曆控件如下面圖片的部分。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_marginTop="15dp"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:gravity="center_vertical"
        android:orientation="horizontal">
        <TextView
            android:id="@+id/calendar_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="2018年"
            android:textColor="@color/text_lable"
            android:textSize="15dp"/>
        <RelativeLayout
            android:id="@+id/layout_calendar_gonext"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:paddingLeft="15dp"
            android:paddingRight="15dp"
            >
            <ImageView
                android:layout_width="10dp"
                android:layout_height="10dp"
                android:layout_centerVertical="true"
                android:src="@mipmap/icon_arrow_right" />
        </RelativeLayout>
    <RelativeLayout
        android:id="@+id/layout_calendar_goup"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:paddingLeft="15dp"
        android:paddingRight="15dp"
        >
        <ImageView
            android:layout_width="10dp"
            android:layout_height="10dp"
            android:layout_centerVertical="true"
            android:src="@mipmap/icon_back_black" />
    </RelativeLayout>

    </RelativeLayout>

    <LinearLayout
        android:id="@+id/calendar_week_header"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="15dp"
        android:gravity="center_vertical"
        android:orientation="horizontal"
        >
        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:text="@string/sun"
            android:textAlignment="center"
            android:textColor="#555"
            android:textSize="13dp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:text="@string/mon"
            android:textAlignment="center"
            android:textColor="#555"
            android:textSize="13dp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:text="@string/tue"
            android:textAlignment="center"
            android:textColor="#555"
            android:textSize="13dp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:text="@string/wed"
            android:textAlignment="center"
            android:textColor="#555"
            android:textSize="13dp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:text="@string/thu"
            android:textAlignment="center"
            android:textColor="#555"
            android:textSize="13dp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:text="@string/fri"
            android:textAlignment="center"
            android:textColor="#555"
            android:textSize="13dp" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"
            android:text="@string/sat"
            android:textAlignment="center"
            android:textColor="#555"
            android:textSize="13dp" />
    </LinearLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/calendar_rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:overScrollMode="never"
        />
</LinearLayout>

定義控件選擇後的背景部分:CalendarDayRelativeLayout.java

import android.content.Context;
import android.graphics.Color;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.util.AttributeSet;
import android.widget.RelativeLayout;


public class CalendarDayRelativeLayout extends RelativeLayout {
    public CalendarDayRelativeLayout(Context context) {
        this(context, null);
    }

    public CalendarDayRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public void isDurationSat(boolean isSaturday) {
        this.setBackground(getResources().getDrawable(R.drawable.appoint_calendar_sat_bg));
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public void isDurationSun(boolean isSunday) {
        this.setBackground(getResources().getDrawable(R.drawable.appoint_calendar_sun_bg));
    }
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public void isETime(boolean etime) {
//        this.setBackgroundResource(getResources().getDrawable(R.drawable.));

        this.setBackground(getResources().getDrawable(R.drawable.appoint_calendar_sat_bg));
    }
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public void isSTime(boolean stime) {
//        this.setBackground(getResources().getDrawable(R.mipmap.appoint_calendar_start_bg));
        this.setBackground(getResources().getDrawable(R.drawable.appoint_calendar_sun_bg));
    }

    /**
     * 同一天
     * */
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public void isSameDay(){
        this.setBackground(getResources().getDrawable(R.drawable.appoint_calendar_same_bg));
    }
}

自定義控件內日期的CalendarDayTextView.java


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;



/**
 * @Description: 日曆內日期
 * @Author MengXY
 * @Date 2019/1/8
*/
public class CalendarDayTextView extends android.support.v7.widget.AppCompatTextView {
    public boolean isToday;
    private boolean isSTime;
    private boolean isETime;
    private Context context;

    public void setEmptyColor(int emptyColor) {
        this.emptyColor = emptyColor;
    }

    public void setFillColor(int fillColor) {
        this.fillColor = fillColor;
    }

    private int emptyColor = Color.parseColor("#00ff00");
    private int fillColor = Color.parseColor("#00ff00");

    private Paint mPaintSTime;
    private Paint mPaintETime;



    public CalendarDayTextView(Context context) {
        super(context);
        initview(context);
    }

    public CalendarDayTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initview(context);
    }

    private void initview(Context context) {
        this.context=context;

//        mPaintSTime = new Paint(Paint.ANTI_ALIAS_FLAG);
//        mPaintSTime.setStyle(Paint.Style.FILL);
//        mPaintSTime.setColor(context.getResources().getColor(R.color.date_time_bg));
//        mPaintSTime.setStrokeWidth(2);
//
//        mPaintETime = new Paint(Paint.ANTI_ALIAS_FLAG);
//        mPaintETime.setStyle(Paint.Style.FILL);
//        mPaintETime.setColor(context.getResources().getColor(R.color.date_time_bg));
//        mPaintETime.setStrokeWidth(2);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //根據當前邏輯開始時間必須先繪製結束時間
//        if (isETime) {
//            canvas.save();
//            //移動到當前控件的中心,以中心爲圓點繪製實心圓
//            canvas.translate(getWidth() / 2, getHeight() / 2);
//            canvas.drawCircle(0, 0, getWidth() / 2 , mPaintETime);
//            canvas.restore();
//            //此處必須將圓移動回開始位置,否則文本顯示會受到影響
//            canvas.translate(0, 0);
//        }
//
//        if (isSTime) {
//            canvas.save();
//            //移動到當前控件的中心,以中心爲圓點繪製實心圓
//            canvas.translate(getWidth() / 2, getHeight() / 2);
//            canvas.drawCircle(0, 0, getWidth() / 2 , mPaintSTime);
//            canvas.restore();
//            //此處必須將圓移動回開始位置,否則文本顯示會受到影響
//            canvas.translate(0, 0);
//        }
        super.onDraw(canvas);
    }

    public void setToday(boolean today) {
        isToday = today;
        this.setTextColor(context.getResources().getColor(R.color.text_main_tab_select));
    }

    public void isETime(boolean etime) {
        isETime = etime;
//        this.setTextColor(context.getResources().getColor(R.color.date_time_tv));
//        this.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
        isSelected(true);
    }

    public void isSTime(boolean stime) {
        isSTime = stime;
        isSelected(true);
//        this.setTextColor(context.getResources().getColor(R.color.date_time_tv));
//        this.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
    }



    public void isSelected(boolean isSelcted){
        if(isSelcted){
            this.setTextColor(context.getResources().getColor(R.color.date_time_tv));
            this.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));
        }else {
            this.setTextColor(context.getResources().getColor(R.color.text_lable));
        }
    }

}

appoint_calendarview.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/appoint_calendarview_item_rv"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

</android.support.v7.widget.RecyclerView>

calendar_text_day.xml

<?xml version="1.0" encoding="utf-8"?>
<com.包名.CalendarDayRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="44dp"
    android:gravity="center"
    android:id="@+id/calendar_day_rl"
    android:layout_marginTop="5dp"
    android:layout_marginBottom="5dp"
    >
    <com..包名.CalendarDayTextView
        android:id="@+id/calendar_day_tv"
        android:layout_width="44dp"
        android:layout_height="44dp"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:textColor="@color/white"
        android:text="31"
        android:includeFontPadding="false"
        android:textSize="13dp"/>
</com..包名.CalendarDayRelativeLayout>

DateUtil.java


import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;


public class DateUtil {

    //Calendar 轉化 String
    public static  String calendarToStr(Calendar calendar,String format) {

//    Calendar calendat = Calendar.getInstance();

        SimpleDateFormat sdf = new SimpleDateFormat(format);

        return sdf.format(calendar.getTime());
    }


    //String 轉化Calendar
    public static Calendar strToCalendar(String str,String format) {

//    String str = "2012-5-27";
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date date = null;
        Calendar calendar = null;
        try {
            date = sdf.parse(str);
            calendar = Calendar.getInstance();
            calendar.setTime(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return calendar;
    }


    //    Date 轉化String
    public static String dateTostr(Date date,String format) {

        SimpleDateFormat sdf = new SimpleDateFormat(format);
//    String dateStr = sdf.format(new Date());
        String dateStr = sdf.format(date);
        return dateStr;
    }


    //  String 轉化Date
    public static Date strToDate(String str,String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date date = null;
        try {
            date = sdf.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }


    //Date 轉化Calendar
    public static Calendar dateToCalendar(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }


    //Calendar轉化Date
    public static Date calendarToDate(Calendar calendar) {
        return calendar.getTime();
    }


    // String 轉成    Timestamp

    public static Timestamp strToTimeStamp(String str) {

//    Timestamp ts = Timestamp.valueOf("2012-1-14 08:11:00");
        return Timestamp.valueOf(str);
    }


    //Date 轉 TimeStamp
    public static Timestamp dateToTimeStamp(Date date,String format) {

        SimpleDateFormat df = new SimpleDateFormat(format);

        String time = df.format(new Date());

        Timestamp ts = Timestamp.valueOf(time);
        return ts;
    }
}

4.資源文件 /drawable

appoint_calendar_sat_bg.xml //開始時間

<shape xmlns:android="http://schemas.android.com/apk/res/android">
        <corners android:topRightRadius="44dp" android:bottomRightRadius="44dp"/>
        <size android:height="44dp"/>
        <solid android:color="#41D2C4"/>
</shape>

appoint_calendar_sun_bg.xml //結束時間

<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <corners
        android:bottomLeftRadius="44dp"
        android:topLeftRadius="44dp" />
    <size android:height="44dp" />
    <solid android:color="#41D2C4" />
</shape>

appoint_calendar_same_bg.xml //開始時間和結束時間是同一天

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
        <solid android:color="@color/date_duration_bg" />
        <corners android:radius="60dp" />
</shape>

/value 

<string name="sun">日</string>
<string name="mon">一</string>
<string name="tue">二</string>
<string name="wed">三</string>
<string name="thu">四</string>
<string name="fri">五</string>
<string name="sat">六</string>

<color name="date_duration_bg">#41D2C4</color>

5.在activity中使用 

activity_selectdate.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/white"
    android:orientation="vertical">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="40dp">

        <FrameLayout
            android:id="@+id/layout_line"
            android:layout_width="10dp"
            android:layout_height="1dp"
            android:layout_centerInParent="true"
            android:background="#35C1B5" />
        <TextView
            android:id="@+id/tv_startime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@+id/layout_line"
            android:layout_marginRight="22.5dp"
            android:textColor="#35C1B5"
            android:textSize="14dp"
            android:text="@string/starTime"
            />
        <TextView
            android:id="@+id/tv_endtime"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@+id/layout_line"
            android:layout_marginLeft="22.5dp"
            android:textColor="#35C1B5"
            android:textSize="14dp"
            android:text="@string/endTime"
            />
    </RelativeLayout>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0.5dp"
        android:layout_marginTop="10dp"
        android:background="@color/bg_line"
        />
    <com.包名.CalendarView
        android:id="@+id/calendarview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:titleColor = "@color/text_lable"
        />
</LinearLayout>

SelectTimeActivity.java

public class SelectTimeActivity extends BaseActivity {

    @BindView(R.id.tv_title)
    TextView tvTitle;
    @BindView(R.id.iv_title_back)
    ImageView ivTitleBack;
    @BindView(R.id.tv_title_left)
    TextView tvTitleLeft;
    @BindView(R.id.layout_title_left)
    RelativeLayout layoutTitleLeft;
    @BindView(R.id.tv_title_right)
    TextView tvTitleRight;
    @BindView(R.id.layout_title_right)
    RelativeLayout layoutTitleRight;
    @BindView(R.id.layout_line)
    FrameLayout layoutLine;
    @BindView(R.id.tv_startime)
    TextView tvStartime;
    @BindView(R.id.tv_endtime)
    TextView tvEndtime;
    @BindView(R.id.calendarview)
    CalendarView calendarview;
    private String starTime;
    private String endTime;
    private boolean isSelecgOk = false;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_selectdate);
        ButterKnife.bind(this);
        setStatusBar(true);
        initView();
    }

    private void initView() {
        tvTitle.setText(getString(R.string.selectTime));
        ivTitleBack.setVisibility(View.GONE);
        tvTitleLeft.setText(getString(R.string.cancel));
        tvTitleRight.setText(getString(R.string.confirm));
        calendarview.setETimeSelListener(new CalendarView.CalendatEtimSelListener() {
            @Override
            public void onETimeSelect(Date date) {
                if (date != null) {
                    endTime = DateUtils.formatData(date, Constant.TFORMATE_YMD);
                    tvEndtime.setText(endTime);
                }else {
                    endTime = null;
                }
            }
        });
        calendarview.setSTimeSelListener(new CalendarView.CalendarSTimeSelListener() {
            @Override
            public void onSTimeSelect(Date date) {
                if (date != null) {
                    starTime = DateUtils.formatData(date, Constant.TFORMATE_YMD);
                    tvStartime.setText(starTime);
                }else {
                    starTime = null;
                }
            }
        });
        calendarview.setCalendaSelListener(new CalendarView.CalendaSelListener() {
            @Override
            public void selectStatus(boolean isOk) {
                isSelecgOk = isOk;
            }
        });
    }

    @OnClick({R.id.tv_title_left, R.id.tv_title_right})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.tv_title_left:
                finish();
                break;
            case R.id.tv_title_right:
                if(TextUtils.isEmpty(starTime)){
                    ToastUtils.showToast(getString(R.string.history_alert1));
                    return;
                }
                if(TextUtils.isEmpty(endTime) || !isSelecgOk){
                    ToastUtils.showToast(getResources().getString(R.string.history_alert));
                    return;
                }
                Intent intent = new Intent();
                intent.putExtra("starTime",starTime);
                intent.putExtra("endTime",endTime);
                setResult(RESULT_OK,intent);
                finish();
                break;
        }
    }
}

RecyclerAdapter引用

implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'

如缺少什麼文件和資源請留言,謝謝啦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章