• Android项目实战(二十九):酒店预定日期选择


    先看需求效果图:

                 

    几个需求点:

    1、显示当月以及下个月的日历 (可自行拓展更多月份)

    2、首次点击选择“开始日期”,再次点击选择"结束日期"

      (1)、如果“开始日期” “结束日期” 相同 

      (2)、如果“开始日期” “结束日期” 不同,且“结束日期” 晚于 “开始日期” 

      (3)、如果“结束日期” 早于 “开始日期” ,重置当前 日期 为 “开始日期”

    3、选择的“开始日期” “结束日期” 显示在 

    难点:

    1、 获取当月以及下个月的日历,一个月多少天,每天星期几

    2、 判断每个日子的点 与  “开始日期” “结束日期” 的关系,用于显示背景色

    技术储备:

    1、浅谈RecyclerView(完美替代ListView,GridView)

    2、Android项目实战(十三):浅谈EventBus

    -----------------------------------------------------------------------------------------------------------------------

    实现思路:

    1、一个外部RecyclerView 用于显示 日历,每一个item 都用于显示一个月的日历             ,下面都称为 外部RecyclerView

    2、外部RecyclerView的每一个Item 内再用一个RecyclerView显示该月的所有日期,每一天都是一个item   ,下面都称为 内部RecyclerView

    3、点击内部RecyclerView的item 日期,添加监听事件,根据是否开始、结束、中间日期来显示 相应的选中背景

    代码实现:

    1、代码框架总览

    2、实体类

    (1)、月份类,外部RecyclerView的数据源实体类

    /**
     * Created by xqx on 2017/1/17.
     * 代表日历上的每一个月份
     */
    public class MonthTimeEntity {
    
        private int year;         //该月份 属于哪一年
        private int month;        // 该月 是哪一个月份
    
        public MonthTimeEntity(int year, int month) {
            this.year = year;
            this.month = month;
        }
    
        public int getYear() {
            return year;
        }
    
        public void setYear(int year) {
            this.year = year;
        }
    
        public int getMonth() {
            return month;
        }
    
        public void setMonth(int month) {
            this.month = month;
        }
    }
    MonthTimeEntity.java

    (2)、日期类,内部RecyclerView的数据源实体类

    /**
     * Created by xqx on 2017/1/17.
     * 日历中每一个月中的 每一个天数
     */
    public class DayTimeEntity {
        private int day ;           //日期,几号
        private int month;           //属于的月份
        private int year;           //属于的年份
    
        private int monthPosition;    //属于的月份位置,注意是该日期属于的月份在外层列表中的position,不是月份
        private int dayPosition;      //属于的日期位置,注意是该日期在每个月(内层列表)中的位置
    
        public DayTimeEntity(int day, int month, int year, int monthPosition) {
            this.day = day;
            this.month = month;
            this.year = year;
            this.monthPosition = monthPosition;
        }
    
    
    
        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 int getMonthPosition() {
            return monthPosition;
        }
    
        public void setMonthPosition(int monthPosition) {
            this.monthPosition = monthPosition;
        }
    
        public int getDayPosition() {
            return dayPosition;
        }
    
        public void setDayPosition(int dayPosition) {
            this.dayPosition = dayPosition;
        }
    
    
    }
    DayTimeEntity.java

    (3)、更新类,用于选择 “开始日期”、“结束日期”之后的刷新适配器操作

    /**
     * Created by xqx on 2017/1/17.
     * 用于EventBus发送消息
     */
    public class UpdataCalendar {
    }
    UpdataCalendar.java

    3、主要实现

    (1)、主界面布局 

    上面就是普通的布局形式,日历用一个RecyclerView显示,这个列表的每一个item都用于显示一个月份的所有天数

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
    
        <!--标题栏-->
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="6dp"
            android:background="@color/white"
            >
    
    
            <!--标题-->
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="预定日期"
                android:layout_centerInParent="true"
                android:textSize="20sp"
                />
        </RelativeLayout>
    
        <ImageView
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#d9d9d9"
            />
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#f2f4f7"
            android:paddingTop="20dp"
            >
            <TextView
                android:id="@+id/plan_time_txt_start"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="开始
    时间"
                android:layout_alignParentTop="true"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"
                android:layout_marginLeft="87dp"
                android:layout_marginStart="87dp"
                android:background="@mipmap/bg_white_circle"
                android:gravity="center"
                />
            <TextView
                android:id="@+id/plan_time_txt_stop"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="结束
    时间"
                android:layout_alignParentTop="true"
                android:layout_alignParentRight="true"
                android:layout_alignParentEnd="true"
                android:layout_marginRight="74dp"
                android:layout_marginEnd="74dp"
                android:background="@mipmap/bg_white_circle"
                android:gravity="center"/>
        </RelativeLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:background="#f2f4f7"
            android:paddingTop="20dp"
            android:paddingBottom="20dp"
            android:paddingLeft="20dp"
            android:paddingRight="20dp"
            >
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="S"
                android:gravity="center"
                />
    
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="M"
                android:gravity="center"
                />
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="T"
                android:gravity="center"
                />
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="W"
                android:gravity="center"
                />
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="T"
                android:gravity="center"
                />
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="F"
                android:gravity="center"
    
                />
            <TextView
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="S"
                android:gravity="center"
                />
        </LinearLayout>
        <android.support.v7.widget.RecyclerView
            android:id="@+id/plan_time_calender"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/white"
            android:paddingLeft="20dp"
            android:paddingRight="20dp"
            >
    
        </android.support.v7.widget.RecyclerView>
    </LinearLayout>
    acticity_main.xml

     

    (2)、日历外部RecyclerView的ViewHolder类,可以看出外层RecyclerView 的 item 只需要一个TextView显示几年几月 和 一个RecyclerView显示该月的天数即可

    import android.content.Context;
    import android.support.v7.widget.GridLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.view.View;
    import android.widget.TextView;
    
    
    /**
     * Created by xqxon 2017/1/17.
     */
    public class MonthTimeViewHolder extends RecyclerView.ViewHolder{
    
        public TextView plan_time_txt_month;                         //文本 2018-1
        public RecyclerView plan_time_recycler_content ;            //月份里面详细日期的列表
        public Context context;                                        //上下文
    
        public MonthTimeViewHolder(View itemView, Context context) {
            super(itemView);
            this.context = context;
            plan_time_recycler_content = (RecyclerView) itemView.findViewById(R.id.plan_time_recycler_content);
            plan_time_txt_month = (TextView) itemView.findViewById(R.id.plan_time_txt_month);
    
            RecyclerView.LayoutManager layoutManager =
                    new GridLayoutManager(context,
                            7,  // 每行显示item项数目
                            GridLayoutManager.VERTICAL, //水平排列
                            false
                    );
    
            plan_time_recycler_content.setLayoutManager(layoutManager);
        }
    }
    MonthTimeViewHolder

    (3)、日历外部RecyclerView的item 布局文件

    <?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="wrap_content">
    
        <TextView
            android:id="@+id/plan_time_txt_month"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/blue"
            android:textSize="16sp"
            android:text="Aug 2017"
            android:layout_marginTop="10dp"
            android:layout_marginLeft="20dp"
            android:layout_marginBottom="10dp"
            />
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/plan_time_recycler_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            >
        </android.support.v7.widget.RecyclerView>
    </LinearLayout>
    item_recycler_timeplan

    (4)、Activity

    public class MonthTimeActivity extends Activity {
    
        private ImageButton back;
        private TextView startTime;          //开始时间
        private TextView stopTime;           //结束时间
    
        private RecyclerView reycycler;
        private MonthTimeAdapter adapter;
        private ArrayList<MonthTimeEntity> datas;
    
    
        public static DayTimeEntity startDay;
        public static DayTimeEntity stopDay;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            initView();
            initData();
    
            EventBus.getDefault().register(this);
    
    
        }
    
        private void initData() {
            startDay = new DayTimeEntity(0,0,0,0);
            stopDay = new DayTimeEntity(-1,-1,-1,-1);
            datas = new ArrayList<>();
    
            Calendar c = Calendar.getInstance();
            int year = c.get(Calendar.YEAR);
            int month = c.get(Calendar.MONTH)+1;
    
            c.add(Calendar.MONTH,1);
            int nextYear = c.get(Calendar.YEAR);
            int nextMonth = c.get(Calendar.MONTH)+1;
    
            datas.add(new MonthTimeEntity(year,month));                //当前月份
            datas.add(new MonthTimeEntity(nextYear,nextMonth));        //下个月
            adapter = new MonthTimeAdapter(datas, MonthTimeActivity.this);
            reycycler.setAdapter(adapter);
    
        }
    
        private void initView() {
            startTime = (TextView) findViewById(R.id.plan_time_txt_start);
            stopTime = (TextView) findViewById(R.id.plan_time_txt_stop);
    
            reycycler = (RecyclerView) findViewById(R.id.plan_time_calender);
            LinearLayoutManager layoutManager =
                    new LinearLayoutManager(this,   // 上下文
                            LinearLayout.VERTICAL,  //垂直布局,
                            false);
    
            reycycler.setLayoutManager(layoutManager);
        }
    
        public void onEventMainThread(UpdataCalendar event) {
            adapter.notifyDataSetChanged();
            startTime.setText(startDay.getMonth()+""+startDay.getDay()+""+"
    ");
            if (stopDay.getDay() == -1) {
                stopTime.setText("结束"+"
    "+"时间");
            }else{
                stopTime.setText(stopDay.getMonth() + "" + stopDay.getDay() + "" + "
    ");
            }
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            EventBus.getDefault().unregister(this);
        }
    }
    MonthTimeActivity.java

      几个核心点:

     1、 两个静态变量的类 用于标记  开始日期和结束日期,和每个日子进行对比,显示不同的背景色

     public static DayTimeEntity startDay;     //开始日期
     public static DayTimeEntity stopDay;   //结束日期

       2、数据源的初始化

       private void initData() {
            startDay = new DayTimeEntity(0,0,0,0);        
            stopDay = new DayTimeEntity(-1,-1,-1,-1);      //注意这里参数都为 -1  不是随便设的 ,后面会用到
            datas = new ArrayList<>();
        
            Calendar c = Calendar.getInstance();         
            int year = c.get(Calendar.YEAR);
            int month = c.get(Calendar.MONTH)+1;           // 获得当前月份的信息, 属于哪一年,哪一月
    
            c.add(Calendar.MONTH,1);                       
            int nextYear = c.get(Calendar.YEAR);
            int nextMonth = c.get(Calendar.MONTH)+1;       // 获得当前月份的下一个月份的信息, 属于哪一年,哪一月。  可以以此类推  不限制于 2个月份
    
            datas.add(new MonthTimeEntity(year,month));                //当前月份的对象  ,对象里信息  包括:哪一年,哪一月
            datas.add(new MonthTimeEntity(nextYear,nextMonth));        //下个月份的对象
            adapter = new MonthTimeAdapter(datas, MonthTimeActivity.this);
            reycycler.setAdapter(adapter);
    
        }

      

    (5)、日历外部RecyclerView的适配器Adapter

    /**
     * Created by xqx on 2017/1/17.
     */
    public class MonthTimeAdapter extends RecyclerView.Adapter<MonthTimeViewHolder>{
    
        private ArrayList<MonthTimeEntity> datas;
        private Context context;
    
        public MonthTimeAdapter(ArrayList<MonthTimeEntity> datas, Context context) {
            this.datas = datas;
            this.context = context;
        }
    
    
        @Override
        public MonthTimeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            MonthTimeViewHolder ret = null;
            // 不需要检查是否复用,因为只要进入此方法,必然没有复用
            // 因为RecyclerView 通过Holder检查复用
            View v = LayoutInflater.from(context).inflate(R.layout.item_recycler_timeplan, parent, false);
            ret = new MonthTimeViewHolder(v,context);
            return ret;
        }
    
        @Override
        public void onBindViewHolder(MonthTimeViewHolder holder, int position) {
            MonthTimeEntity monthTimeEntity = datas.get(position);
            holder.plan_time_txt_month.setText(monthTimeEntity.getYear()+"--"+ monthTimeEntity.getMonth());  //显示 几年--几月
            //得到该月份的第一天
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.YEAR, monthTimeEntity.getYear());          //指定年份
            calendar.set(Calendar.MONTH, monthTimeEntity.getMonth() - 1);        //指定月份 Java月份从0开始算
            calendar.set(Calendar.DAY_OF_MONTH,1);                           // 指定天数 ,这三行是为了得到 这一年这一月的第一天
    
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);             //得到该月份第一天 是星期几
            ArrayList<DayTimeEntity> days = new ArrayList<DayTimeEntity>();
            for (int i = 0; i < dayOfWeek-1; i++) {                          //
                days.add(new DayTimeEntity(0, monthTimeEntity.getMonth(), monthTimeEntity.getYear(),position));
            }
            calendar.add(Calendar.MONTH, 1);// 加一个月,变为下月的1号
            calendar.add(Calendar.DATE, -1);// 减去一天,变为当月最后一天
            for (int i = 1; i <= calendar.get(Calendar.DAY_OF_MONTH); i++) {     //添加 该月份的天数   一号 到 该月的最后一天
                days.add(new DayTimeEntity(i, monthTimeEntity.getMonth(), monthTimeEntity.getYear(),position));
            }
    
            DayTimeAdapter adapter = new DayTimeAdapter(days,context);
            holder.plan_time_recycler_content.setAdapter(adapter);
    
        }
    
        @Override
        public int getItemCount() {
            int ret = 0;
            if (datas!=null){
                ret = datas.size();
            }
            return ret;
        }
    }
    MonthTimeAdapter.java

    核心代码:

          //得到该月份的第一天
            Calendar calendar = Calendar.getInstance();
            calendar.set(Calendar.YEAR, monthTimeEntity.getYear());          //指定年份
            calendar.set(Calendar.MONTH, monthTimeEntity.getMonth() - 1);        //指定月份 Java月份从0开始算
            calendar.set(Calendar.DAY_OF_MONTH,1);                           // 指定天数 ,这三行是为了得到 这一年这一月的第一天
    
            int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);             //得到该月份第一天 是星期几
         for (int i = 0; i < dayOfWeek-1; i++) {                          //
                days.add(new DayTimeEntity(0, monthTimeEntity.getMonth(), monthTimeEntity.getYear(),position));   //填充空白天数
            }

    目的是实现 :比如第一天是星期3 ,那么日历上 星期日,星期一,星期二的位置 要为空白  

           意味着一个天数的item getDay() == 0 ,说明这天是空白天数 

       
            calendar.add(Calendar.MONTH, 1);// 加一个月,变为下月的1号
            calendar.add(Calendar.DATE, -1);// 减去一天,变为当月最后一天
            for (int i = 1; i <= calendar.get(Calendar.DAY_OF_MONTH); i++) {     // 添加 该月份的天数   一号 到 该月的最后一天
                days.add(new DayTimeEntity(i, monthTimeEntity.getMonth(), monthTimeEntity.getYear(),position));
            } 

    目的是实现:得到该月份的最后一天是几号,然后从1号到最后一天都作为数据源添加到内部的recyclerview中。

    以上是外层Recyclerview(每一个Item是一个月份)的相关代码

    -------------------------------------------------------------------------------------------------

    (6)  外部RecyclerView的 Item中的内部RecyclerView ,每一个item都是该月份的一天

      item布局:  就只有一个textview ,用于显示 几号

    <?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="wrap_content"
        android:layout_marginTop="2dp"
        android:layout_marginBottom="2dp"
        android:paddingTop="6dp"
        android:paddingBottom="6dp"
        android:id="@+id/select_ly_day"
        >
    
        <TextView
            android:id="@+id/select_txt_day"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=""
            android:layout_gravity="center"
            android:gravity="center"
            />
    
    </LinearLayout>
    item_recycler_selectday.xml

    (7)内部RecyclerView的ViewHolder

    **
     * Created by xqx on 2017/1/17.
     *
     */
    public class DayTimeViewHolder extends RecyclerView.ViewHolder{
    
        public TextView select_txt_day;      //日期文本
        public LinearLayout select_ly_day;       //父容器 , 用于点击日期
    
        public DayTimeViewHolder(View itemView) {
            super(itemView);
            select_ly_day = (LinearLayout) itemView.findViewById(R.id.select_ly_day);
            select_txt_day = (TextView) itemView.findViewById(R.id.select_txt_day);
        }
    }
    DayTimeViewHolder.java

    (8)内部RecyclerView的适配器Adapter

    package com.maiji.calendardemo.selectTime;
    
    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    
    import com.maiji.calendardemo.MonthTimeActivity;
    import com.maiji.calendardemo.R;
    import com.maiji.calendardemo.entity.DayTimeEntity;
    import com.maiji.calendardemo.entity.UpdataCalendar;
    
    import java.util.ArrayList;
    
    import de.greenrobot.event.EventBus;
    
    /**
     * Created by xqx on 2017/1/17.
     */
    public class DayTimeAdapter extends RecyclerView.Adapter<DayTimeViewHolder>{
    
        private ArrayList<DayTimeEntity> days;
        private Context context;
    
        public DayTimeAdapter(ArrayList<DayTimeEntity> days, Context context) {
            this.days = days;
            this.context = context;
    
        }
    
        @Override
        public DayTimeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            DayTimeViewHolder ret = null;
            // 不需要检查是否复用,因为只要进入此方法,必然没有复用
            // 因为RecyclerView 通过Holder检查复用
            View v = LayoutInflater.from(context).inflate(R.layout.item_recycler_selectday, parent, false);
            ret = new DayTimeViewHolder(v);
    
            return ret;
        }
    
        @Override
        public void onBindViewHolder(final DayTimeViewHolder holder, final int position) {
            final DayTimeEntity dayTimeEntity = days.get(position);
            //显示日期
            if (dayTimeEntity.getDay()!=0) {
                holder.select_txt_day.setText(dayTimeEntity.getDay() + "");
                holder.select_ly_day.setEnabled(true);
            }else{
                holder.select_ly_day.setEnabled(false);
            }
            holder.select_ly_day.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (MonthTimeActivity.startDay.getYear() == 0 ){          // 第一次点击开始的位置,因为开始默认参数是 0,0,0,0
                        MonthTimeActivity.startDay.setDay(dayTimeEntity.getDay());           // 该item 天数的 年月日等信息  赋给  开始日期
                        MonthTimeActivity.startDay.setMonth(dayTimeEntity.getMonth());
                        MonthTimeActivity.startDay.setYear(dayTimeEntity.getYear());
                        MonthTimeActivity.startDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                        MonthTimeActivity.startDay.setDayPosition(position);
                    }else if(MonthTimeActivity.startDay.getYear()>0 && MonthTimeActivity.stopDay.getYear() ==-1){      //已经点击了开始 ,点击结束位置,(默认结束位置-1,-1,-1,-1 说明还没有点击结束位置)
                        if (dayTimeEntity.getYear()> MonthTimeActivity.startDay.getYear()) {
                            //如果选中的年份大于开始的年份,说明结束日期肯定大于开始日期 ,合法的 ,将该item的天数的 信息  赋给 结束日期
                            MonthTimeActivity.stopDay.setDay(dayTimeEntity.getDay());
                            MonthTimeActivity.stopDay.setMonth(dayTimeEntity.getMonth());
                            MonthTimeActivity.stopDay.setYear(dayTimeEntity.getYear());
                            MonthTimeActivity.stopDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                            MonthTimeActivity.stopDay.setDayPosition(position);
                        }else if (dayTimeEntity.getYear() == MonthTimeActivity.startDay.getYear()){
                            //如果选中的年份 等于 选中的年份
                            if (dayTimeEntity.getMonth()> MonthTimeActivity.startDay.getMonth()){
                                //如果改item的天数的月份大于开始日期的月份,说明结束日期肯定大于开始日期 ,合法的 ,将该item的天数的 信息  赋给 结束日期
                                MonthTimeActivity.stopDay.setDay(dayTimeEntity.getDay());
                                MonthTimeActivity.stopDay.setMonth(dayTimeEntity.getMonth());
                                MonthTimeActivity.stopDay.setYear(dayTimeEntity.getYear());
                                MonthTimeActivity.stopDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                                MonthTimeActivity.stopDay.setDayPosition(position);
                            }else if(dayTimeEntity.getMonth() == MonthTimeActivity.startDay.getMonth()){
                                //年份月份 都相等
                                if (dayTimeEntity.getDay() >= MonthTimeActivity.startDay.getDay()){
                                    //判断天数 ,如果 该item的天数的 日子大于等于 开始日期的 日子 ,说明结束日期合法的 ,将该item的天数的 信息  赋给 结束日期
                                    MonthTimeActivity.stopDay.setDay(dayTimeEntity.getDay());
                                    MonthTimeActivity.stopDay.setMonth(dayTimeEntity.getMonth());
                                    MonthTimeActivity.stopDay.setYear(dayTimeEntity.getYear());
                                    MonthTimeActivity.stopDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                                    MonthTimeActivity.stopDay.setDayPosition(position);
                                }else{
                                    //天数小与初始  从新选择开始  ,结束日期重置,开始日期为当前的位置的天数的信息
                                    MonthTimeActivity.startDay.setDay(dayTimeEntity.getDay());
                                    MonthTimeActivity.startDay.setMonth(dayTimeEntity.getMonth());
                                    MonthTimeActivity.startDay.setYear(dayTimeEntity.getYear());
                                    MonthTimeActivity.startDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                                    MonthTimeActivity.startDay.setDayPosition(position);
                                    MonthTimeActivity.stopDay.setDay(-1);
                                    MonthTimeActivity.stopDay.setMonth(-1);
                                    MonthTimeActivity.stopDay.setYear(-1);
                                    MonthTimeActivity.stopDay.setMonthPosition(-1);
                                    MonthTimeActivity.stopDay.setDayPosition(-1);
                                }
                            }else {
                                //选中的月份 比开始日期的月份还小,说明 结束位置不合法,结束日期重置,开始日期为当前的位置的天数的信息
                                MonthTimeActivity.startDay.setDay(dayTimeEntity.getDay());
                                MonthTimeActivity.startDay.setMonth(dayTimeEntity.getMonth());
                                MonthTimeActivity.startDay.setYear(dayTimeEntity.getYear());
                                MonthTimeActivity.startDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                                MonthTimeActivity.startDay.setDayPosition(position);
                                MonthTimeActivity.stopDay.setDay(-1);
                                MonthTimeActivity.stopDay.setMonth(-1);
                                MonthTimeActivity.stopDay.setYear(-1);
                                MonthTimeActivity.stopDay.setMonthPosition(-1);
                                MonthTimeActivity.stopDay.setDayPosition(-1);
                            }
    
                        }else{
                            //选中的年份 比开始日期的年份还小,说明 结束位置不合法,结束日期重置,开始日期为当前的位置的天数的信息
                            MonthTimeActivity.startDay.setDay(dayTimeEntity.getDay());
                            MonthTimeActivity.startDay.setMonth(dayTimeEntity.getMonth());
                            MonthTimeActivity.startDay.setYear(dayTimeEntity.getYear());
                            MonthTimeActivity.startDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                            MonthTimeActivity.startDay.setDayPosition(position);
                            MonthTimeActivity.stopDay.setDay(-1);
                            MonthTimeActivity.stopDay.setMonth(-1);
                            MonthTimeActivity.stopDay.setYear(-1);
                            MonthTimeActivity.stopDay.setMonthPosition(-1);
                            MonthTimeActivity.stopDay.setDayPosition(-1);
                        }
                    }else if(MonthTimeActivity.startDay.getYear()>0 && MonthTimeActivity.startDay.getYear()>1){      //已经点击开始和结束   第三次点击 ,重新点击开始
                        MonthTimeActivity.startDay.setDay(dayTimeEntity.getDay());
                        MonthTimeActivity.startDay.setMonth(dayTimeEntity.getMonth());
                        MonthTimeActivity.startDay.setYear(dayTimeEntity.getYear());
                        MonthTimeActivity.startDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                        MonthTimeActivity.startDay.setDayPosition(position);
                        MonthTimeActivity.stopDay.setDay(-1);
                        MonthTimeActivity.stopDay.setMonth(-1);
                        MonthTimeActivity.stopDay.setYear(-1);
                        MonthTimeActivity.stopDay.setMonthPosition(-1);
                        MonthTimeActivity.stopDay.setDayPosition(-1);
                    }
                    EventBus.getDefault().post(new UpdataCalendar()); // 发消息刷新适配器,目的为了显示日历上各个日期的背景颜色
                }
            });
    
    
            if (MonthTimeActivity.startDay.getYear()== dayTimeEntity.getYear() && MonthTimeActivity.startDay.getMonth() == dayTimeEntity.getMonth() && MonthTimeActivity.startDay.getDay() == dayTimeEntity.getDay()
                    && MonthTimeActivity.stopDay.getYear()== dayTimeEntity.getYear() && MonthTimeActivity.stopDay.getMonth() == dayTimeEntity.getMonth() && MonthTimeActivity.stopDay.getDay() == dayTimeEntity.getDay() ){
                //开始和结束同一天
                holder.select_ly_day.setBackgroundResource(R.drawable.bg_time_startstop);
    
            }
            else if (MonthTimeActivity.startDay.getYear()== dayTimeEntity.getYear() && MonthTimeActivity.startDay.getMonth() == dayTimeEntity.getMonth() && MonthTimeActivity.startDay.getDay() == dayTimeEntity.getDay()){
                //该item是 开始日期
                holder.select_ly_day.setBackgroundResource(R.drawable.bg_time_start);
            }else if(MonthTimeActivity.stopDay.getYear()== dayTimeEntity.getYear() && MonthTimeActivity.stopDay.getMonth() == dayTimeEntity.getMonth() && MonthTimeActivity.stopDay.getDay() == dayTimeEntity.getDay()){
                //该item是 结束日期
                holder.select_ly_day.setBackgroundResource(R.drawable.bg_time_stop);
            }else if(dayTimeEntity.getMonthPosition()>= MonthTimeActivity.startDay.getMonthPosition() && dayTimeEntity.getMonthPosition()<= MonthTimeActivity.stopDay.getMonthPosition()){
                //处于开始和结束之间的点
                if (dayTimeEntity.getMonthPosition()== MonthTimeActivity.startDay.getMonthPosition()&& dayTimeEntity.getMonthPosition()== MonthTimeActivity.stopDay.getMonthPosition()){
                    //开始和结束是一个月份
                    if (dayTimeEntity.getDay()> MonthTimeActivity.startDay.getDay() && dayTimeEntity.getDay() < MonthTimeActivity.stopDay.getDay()) {
                        holder.select_ly_day.setBackgroundResource(R.color.blue);
                    }else{
                        holder.select_ly_day.setBackgroundResource(R.color.white);
                    }
                }else if(MonthTimeActivity.startDay.getMonthPosition() != MonthTimeActivity.stopDay.getMonthPosition()){
                    // 日期和 开始 不是一个月份
                    if (dayTimeEntity.getMonthPosition()== MonthTimeActivity.startDay.getMonthPosition() && dayTimeEntity.getDay()> MonthTimeActivity.startDay.getDay()){
                        //和初始相同月  天数往后
                        holder.select_ly_day.setBackgroundResource(R.color.blue);
                    }else if(dayTimeEntity.getMonthPosition()== MonthTimeActivity.stopDay.getMonthPosition() && dayTimeEntity.getDay()< MonthTimeActivity.stopDay.getDay()){
                        //和结束相同月   天数往前
                        holder.select_ly_day.setBackgroundResource(R.color.blue);
                    }else if(dayTimeEntity.getMonthPosition()!= MonthTimeActivity.startDay.getMonthPosition() && dayTimeEntity.getMonthPosition()!= MonthTimeActivity.stopDay.getMonthPosition()){
                        //和 开始结束都不是同一个月
                        holder.select_ly_day.setBackgroundResource(R.color.blue);
                    }else{
                        holder.select_ly_day.setBackgroundResource(R.color.white);
                    }
                }
    
            }else{
                holder.select_ly_day.setBackgroundResource(R.color.white);
            }
    
        }
    
        @Override
        public int getItemCount() {
            int ret = 0;
            if (days!=null){
                ret = days.size();
            }
            return ret;
        }
    }
    DayTimeAdapter.java

      核心代码:

      1、 不是日期的item不可点击,即 getDay()的到参数 为0的不可点击,详情看(5) 

         //显示日期
            if (dayTimeEntity.getDay()!=0) {
                holder.select_txt_day.setText(dayTimeEntity.getDay() + "");
                holder.select_ly_day.setEnabled(true);
            }else{
                holder.select_ly_day.setEnabled(false);
            }

       2、 item设置点击监听事件,标记并赋值“开始位置”和“结束位置”

    holder.select_ly_day.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (MonthTimeActivity.startDay.getYear() == 0 ){          // 第一次点击开始的位置,因为开始默认参数是 0,0,0,0
                        MonthTimeActivity.startDay.setDay(dayTimeEntity.getDay());           // 该item 天数的 年月日等信息  赋给  开始日期
                        MonthTimeActivity.startDay.setMonth(dayTimeEntity.getMonth());
                        MonthTimeActivity.startDay.setYear(dayTimeEntity.getYear());
                        MonthTimeActivity.startDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                        MonthTimeActivity.startDay.setDayPosition(position);
                    }else if(MonthTimeActivity.startDay.getYear()>0 && MonthTimeActivity.stopDay.getYear() ==-1){      //已经点击了开始 ,点击结束位置,(默认结束位置-1,-1,-1,-1 说明还没有点击结束位置)
                        if (dayTimeEntity.getYear()> MonthTimeActivity.startDay.getYear()) {
                            //如果选中的年份大于开始的年份,说明结束日期肯定大于开始日期 ,合法的 ,将该item的天数的 信息  赋给 结束日期
                            MonthTimeActivity.stopDay.setDay(dayTimeEntity.getDay());
                            MonthTimeActivity.stopDay.setMonth(dayTimeEntity.getMonth());
                            MonthTimeActivity.stopDay.setYear(dayTimeEntity.getYear());
                            MonthTimeActivity.stopDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                            MonthTimeActivity.stopDay.setDayPosition(position);
                        }else if (dayTimeEntity.getYear() == MonthTimeActivity.startDay.getYear()){
                            //如果选中的年份 等于 选中的年份
                            if (dayTimeEntity.getMonth()> MonthTimeActivity.startDay.getMonth()){
                                //如果改item的天数的月份大于开始日期的月份,说明结束日期肯定大于开始日期 ,合法的 ,将该item的天数的 信息  赋给 结束日期
                                MonthTimeActivity.stopDay.setDay(dayTimeEntity.getDay());
                                MonthTimeActivity.stopDay.setMonth(dayTimeEntity.getMonth());
                                MonthTimeActivity.stopDay.setYear(dayTimeEntity.getYear());
                                MonthTimeActivity.stopDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                                MonthTimeActivity.stopDay.setDayPosition(position);
                            }else if(dayTimeEntity.getMonth() == MonthTimeActivity.startDay.getMonth()){
                                //年份月份 都相等
                                if (dayTimeEntity.getDay() >= MonthTimeActivity.startDay.getDay()){
                                    //判断天数 ,如果 该item的天数的 日子大于等于 开始日期的 日子 ,说明结束日期合法的 ,将该item的天数的 信息  赋给 结束日期
                                    MonthTimeActivity.stopDay.setDay(dayTimeEntity.getDay());
                                    MonthTimeActivity.stopDay.setMonth(dayTimeEntity.getMonth());
                                    MonthTimeActivity.stopDay.setYear(dayTimeEntity.getYear());
                                    MonthTimeActivity.stopDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                                    MonthTimeActivity.stopDay.setDayPosition(position);
                                }else{
                                    //天数小与初始  从新选择开始  ,结束日期重置,开始日期为当前的位置的天数的信息
                                    MonthTimeActivity.startDay.setDay(dayTimeEntity.getDay());
                                    MonthTimeActivity.startDay.setMonth(dayTimeEntity.getMonth());
                                    MonthTimeActivity.startDay.setYear(dayTimeEntity.getYear());
                                    MonthTimeActivity.startDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                                    MonthTimeActivity.startDay.setDayPosition(position);
                                    MonthTimeActivity.stopDay.setDay(-1);
                                    MonthTimeActivity.stopDay.setMonth(-1);
                                    MonthTimeActivity.stopDay.setYear(-1);
                                    MonthTimeActivity.stopDay.setMonthPosition(-1);
                                    MonthTimeActivity.stopDay.setDayPosition(-1);
                                }
                            }else {
                                //选中的月份 比开始日期的月份还小,说明 结束位置不合法,结束日期重置,开始日期为当前的位置的天数的信息
                                MonthTimeActivity.startDay.setDay(dayTimeEntity.getDay());
                                MonthTimeActivity.startDay.setMonth(dayTimeEntity.getMonth());
                                MonthTimeActivity.startDay.setYear(dayTimeEntity.getYear());
                                MonthTimeActivity.startDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                                MonthTimeActivity.startDay.setDayPosition(position);
                                MonthTimeActivity.stopDay.setDay(-1);
                                MonthTimeActivity.stopDay.setMonth(-1);
                                MonthTimeActivity.stopDay.setYear(-1);
                                MonthTimeActivity.stopDay.setMonthPosition(-1);
                                MonthTimeActivity.stopDay.setDayPosition(-1);
                            }
    
                        }else{
                            //选中的年份 比开始日期的年份还小,说明 结束位置不合法,结束日期重置,开始日期为当前的位置的天数的信息
                            MonthTimeActivity.startDay.setDay(dayTimeEntity.getDay());
                            MonthTimeActivity.startDay.setMonth(dayTimeEntity.getMonth());
                            MonthTimeActivity.startDay.setYear(dayTimeEntity.getYear());
                            MonthTimeActivity.startDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                            MonthTimeActivity.startDay.setDayPosition(position);
                            MonthTimeActivity.stopDay.setDay(-1);
                            MonthTimeActivity.stopDay.setMonth(-1);
                            MonthTimeActivity.stopDay.setYear(-1);
                            MonthTimeActivity.stopDay.setMonthPosition(-1);
                            MonthTimeActivity.stopDay.setDayPosition(-1);
                        }
                    }else if(MonthTimeActivity.startDay.getYear()>0 && MonthTimeActivity.startDay.getYear()>1){      //已经点击开始和结束   第三次点击 ,重新点击开始
                        MonthTimeActivity.startDay.setDay(dayTimeEntity.getDay());
                        MonthTimeActivity.startDay.setMonth(dayTimeEntity.getMonth());
                        MonthTimeActivity.startDay.setYear(dayTimeEntity.getYear());
                        MonthTimeActivity.startDay.setMonthPosition(dayTimeEntity.getMonthPosition());
                        MonthTimeActivity.startDay.setDayPosition(position);
                        MonthTimeActivity.stopDay.setDay(-1);
                        MonthTimeActivity.stopDay.setMonth(-1);
                        MonthTimeActivity.stopDay.setYear(-1);
                        MonthTimeActivity.stopDay.setMonthPosition(-1);
                        MonthTimeActivity.stopDay.setDayPosition(-1);
                    }
                    EventBus.getDefault().post(new UpdataCalendar()); // 发消息刷新适配器,目的为了显示日历上各个日期的背景颜色
                }
            });

      3、根据每个item的年月日,在外部列表中的位置,在内部列表中的位置 信息 和“开始日期”、“结束日期”的信息对比,设置相应的背景色

    if (MonthTimeActivity.startDay.getYear()== dayTimeEntity.getYear() && MonthTimeActivity.startDay.getMonth() == dayTimeEntity.getMonth() && MonthTimeActivity.startDay.getDay() == dayTimeEntity.getDay()
    && MonthTimeActivity.stopDay.getYear()== dayTimeEntity.getYear() && MonthTimeActivity.stopDay.getMonth() == dayTimeEntity.getMonth() && MonthTimeActivity.stopDay.getDay() == dayTimeEntity.getDay() ){
    //开始和结束同一天
    holder.select_ly_day.setBackgroundResource(R.drawable.bg_time_startstop);
    holder.select_txt_day.setTextColor(context.getResources().getColor(R.color.white));
    }
    else if (MonthTimeActivity.startDay.getYear()== dayTimeEntity.getYear() && MonthTimeActivity.startDay.getMonth() == dayTimeEntity.getMonth() && MonthTimeActivity.startDay.getDay() == dayTimeEntity.getDay()){
    //该item是 开始日期
    holder.select_ly_day.setBackgroundResource(R.drawable.bg_time_start);
    holder.select_txt_day.setTextColor(context.getResources().getColor(R.color.white));
    }else if(MonthTimeActivity.stopDay.getYear()== dayTimeEntity.getYear() && MonthTimeActivity.stopDay.getMonth() == dayTimeEntity.getMonth() && MonthTimeActivity.stopDay.getDay() == dayTimeEntity.getDay()){
    //该item是 结束日期
    holder.select_ly_day.setBackgroundResource(R.drawable.bg_time_stop);
    holder.select_txt_day.setTextColor(context.getResources().getColor(R.color.white));
    }else if(dayTimeEntity.getMonthPosition()>= MonthTimeActivity.startDay.getMonthPosition() && dayTimeEntity.getMonthPosition()<= MonthTimeActivity.stopDay.getMonthPosition()){
    //处于开始和结束之间的点
    if (dayTimeEntity.getMonthPosition()== MonthTimeActivity.startDay.getMonthPosition()&& dayTimeEntity.getMonthPosition()== MonthTimeActivity.stopDay.getMonthPosition()){
    //开始和结束是一个月份
    if (dayTimeEntity.getDay()> MonthTimeActivity.startDay.getDay() && dayTimeEntity.getDay() < MonthTimeActivity.stopDay.getDay()) {
    holder.select_ly_day.setBackgroundResource(R.color.blue);
    holder.select_txt_day.setTextColor(context.getResources().getColor(R.color.white));
    }else{
    holder.select_ly_day.setBackgroundResource(R.color.white);
    holder.select_txt_day.setTextColor(context.getResources().getColor(R.color.txtColor));
    }
    }else if(MonthTimeActivity.startDay.getMonthPosition() != MonthTimeActivity.stopDay.getMonthPosition()){
    // 日期和 开始 不是一个月份
    if (dayTimeEntity.getMonthPosition()== MonthTimeActivity.startDay.getMonthPosition() && dayTimeEntity.getDay()> MonthTimeActivity.startDay.getDay()){
    //和初始相同月 天数往后
    holder.select_ly_day.setBackgroundResource(R.color.blue);
    holder.select_txt_day.setTextColor(context.getResources().getColor(R.color.white));
    }else if(dayTimeEntity.getMonthPosition()== MonthTimeActivity.stopDay.getMonthPosition() && dayTimeEntity.getDay()< MonthTimeActivity.stopDay.getDay()){
    //和结束相同月 天数往前
    if (dayTimeEntity.getDay()<=0){
    holder.select_ly_day.setBackgroundResource(R.color.white);
    holder.select_txt_day.setTextColor(context.getResources().getColor(R.color.txtColor));
    }else {
    holder.select_ly_day.setBackgroundResource(R.color.blue);
    holder.select_txt_day.setTextColor(context.getResources().getColor(R.color.white));
    }
    }else if(dayTimeEntity.getMonthPosition()!= MonthTimeActivity.startDay.getMonthPosition() && dayTimeEntity.getMonthPosition()!= MonthTimeActivity.stopDay.getMonthPosition()){
    //和 开始结束都不是同一个月
    holder.select_ly_day.setBackgroundResource(R.color.blue);
    holder.select_txt_day.setTextColor(context.getResources().getColor(R.color.white));
    }else{
    holder.select_ly_day.setBackgroundResource(R.color.white);
    holder.select_txt_day.setTextColor(context.getResources().getColor(R.color.txtColor));
    }
    }

    }else{
    holder.select_ly_day.setBackgroundResource(R.color.white);
    holder.select_txt_day.setTextColor(context.getResources().getColor(R.color.txtColor));
    }

      判断逻辑都在代码中有注释

    (9) 资源文件的代码

      1、drawable文件

      bg_time_start.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <!--开始日期的背景-->
        <corners android:bottomLeftRadius="20dp"
            android:topLeftRadius="20dp"
            ></corners>
        <solid android:color="#4ab7e8"></solid>
    </shape>

      bg_time_stop.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <!--结束日期的背景-->
        <corners android:bottomRightRadius="20dp"
            android:topRightRadius="20dp"
            ></corners>
        <solid android:color="#4ab7e8"></solid>
    </shape>

      bg_time_startstop.xml

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android">
        <!--开始日期和结束日期同一天的背景-->
        <corners android:radius="20dp"
            ></corners>
        <solid android:color="#4ab7e8"></solid>
    </shape>

      (2)、colors.xml

    <color name="white">#fff</color>
    
    <color name="blue">#4ab7e8</color>

     

    --------------------------------------------------------------------------------------------------------------------------

    GitHub:仿美团酒店预订日期选择

    另:强制当天作为开始日期,只选择结束日期,可以调整结束日期和开始日期的间隔时间限制

    GitHub: 仿美团酒店预订日期选择(强制当天作为开始日期)

  • 相关阅读:
    MySQL性能优化(二):优化数据库的设计
    MySQL性能优化(一):优化方式
    PTA 07-图4 哈利·波特的考试 (25分)
    PTA 06-图3 六度空间 (30分)
    PTA 06-图2 Saving James Bond
    PTA 06-图1 列出连通集 (25分)
    PTA 05-树9 Huffman Codes (30分)
    PTA 05-树8 File Transfer (25分)
    PTA 05-树7 堆中的路径 (25分)
    PTA 04-树6 Complete Binary Search Tree (30分)
  • 原文地址:https://www.cnblogs.com/xqxacm/p/6297151.html
Copyright © 2020-2023  润新知