Android項目實戰(二十九):酒店預約日期選擇

先看需求效果圖:html

             

 

 

幾個需求點:java

一、顯示當月以及下個月的日曆 (可自行拓展更多月份)android

二、首次點擊選擇「開始日期」,再次點擊選擇"結束日期"git

  (1)、若是「開始日期」 「結束日期」 相同 github

  (2)、若是「開始日期」 「結束日期」 不一樣,且「結束日期」 晚於 「開始日期」 框架

 

  (3)、若是「結束日期」 早於 「開始日期」 ,重置當前 日期 爲 「開始日期」ide

 

三、選擇的「開始日期」 「結束日期」 顯示在 佈局

 

難點:post

一、 獲取當月以及下個月的日曆,一個月多少天,天天星期幾this

二、 判斷每一個日子的點 與  「開始日期」 「結束日期」 的關係,用於顯示背景色

 

技術儲備:

一、淺談RecyclerView(完美替代ListView,GridView)

二、Android項目實戰(十三):淺談EventBus

 

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

 

實現思路:

一、一個外部RecyclerView 用於顯示 日曆,每個item 都用於顯示一個月的日曆             ,下面都稱爲 外部RecyclerView

二、外部RecyclerView的每個Item 內再用一個RecyclerView顯示該月的全部日期,每一天都是一個item   ,下面都稱爲 內部RecyclerView

三、點擊內部RecyclerView的item 日期,添加監聽事件,根據是否開始、結束、中間日期來顯示 相應的選中背景

 

 

代碼實現:

一、代碼框架總覽

 

二、實體類

(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

 

 

三、主要實現

(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="開始\n時間"
            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="結束\n時間"
            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()+""+"\n");
        if (stopDay.getDay() == -1) {
            stopTime.setText("結束"+"\n"+"時間");
        }else{
            stopTime.setText(stopDay.getMonth() + "" + stopDay.getDay() + "" + "\n");
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}
MonthTimeActivity.java

  幾個核心點:

 一、 兩個靜態變量的類 用於標記  開始日期和結束日期,和每一個日子進行對比,顯示不一樣的背景色

 public static DayTimeEntity startDay;     //開始日期
 public static DayTimeEntity stopDay;   //結束日期

   二、數據源的初始化

   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

 

  核心代碼:

  一、 不是日期的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);
        }

 

   二、 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()); // 發消息刷新適配器,目的爲了顯示日曆上各個日期的背景顏色
            }
        });

  三、根據每一個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) 資源文件的代碼

  一、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: 仿美團酒店預訂日期選擇(強制當天做爲開始日期)

相關文章
相關標籤/搜索