編輯:關於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="開始\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
幾個核心點:
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);
}
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);
}
判斷邏輯都在代碼中有注釋
(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>
--------------------------------------------------------------------------------------------------------------------------
源碼下載
MVP模式在Android項目中的使用,mvp模式android項目
MVP模式在Android項目中的使用,mvp模式android項目 以前在寫項目的時候,沒有過多考慮架構模式的問題,因為之前一直做J2EE開發,而J2EE都是采用MV
Android Eclipse 導入 AS Gradle AAR 庫手冊
Android Eclipse 導入 AS Gradle AAR 庫手冊 序言 這是一篇半技術類文章。眾所周知現在Google主推Android Studio開發工具,而
我的第一節Android課,第一節Android課
我的第一節Android課,第一節Android課 我的第一節安卓課程,今天非比尋常的一天,我開始了我程序猿之路的第一節安卓課程,安卓課程只是我的一個興趣班,我的本專業
Android APP 兩種用程序撥號的方式,androidapp
Android APP 兩種用程序撥號的方式,androidapp想在APP中添加一個撥號功能該怎樣做呢?Android提供了兩種方式,一種是ACTION_CALL方式直