Android仿IOS Dialog底部彈出月曆式時間選擇器

最近項目需求要寫一個類IOS並且是月曆樣式的時間選擇器,如圖:
需求

少廢話,成品如下:
完成圖

1. 思路

界面部分

<LinearLayout
	<LinearLayout/>
	<LinearLayout/>
	<LinearLayout/>
	<RecyclerView/>
/>

上面三個線性佈局easy,下面的RecyclerView也很簡單,只是,初學不太會用,花了點時間研究,主要是GridLayoutManager的幾個參數、方法。

    <android.support.v7.widget.RecyclerView
        android:id="@+id/date_picker_recycler_view"
        android:paddingTop="10dp"
        android:paddingBottom="10dp"
        android:background="@color/white"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

注意到需求上面左右是沒有邊距的,所以只是加了上下的padding。
並且各個日期之間也是沒有邊距的所以item也很簡單,
height沒有設置成wrap_content完全是因爲太高了,不好看。
android:stateListAnimator="@null"這句是爲了取消Button點擊產生的陰影,貌似API21以下還是有,待解決。

<?xml version="1.0" encoding="utf-8"?>
<Button
    android:id="@+id/btn_date_item_date"
    android:textColor="@color/monthForm_text"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@color/white"
    android:layout_width="wrap_content"
    android:layout_height="35dp"
    android:stateListAnimator="@null"/>

然後就是RecyclerView的設置了
RecyclerView的騷操作可以說完全就是靠LayoutManager完成的。
這裏我們用到的是網頁佈局,直接貼代碼。

        recyclerView.setLayoutManager(new GridLayoutManager(context,7));

第一個參數context,第二個參數是列數,就完了。

如果要給item設置間距

如果要每個item之間有間距,我不知道高手是怎麼實現的,我是通過給item設置margin實現的。

因爲如果item寬度是wrap_content,假如列數爲7,recyclerView它會根據屏幕寬度把item的寬度設置爲屏幕寬度的1/7,假如是定寬,那就排不了了,要麼一行好多個要麼一行幾個,是吧,假如屏幕1000px,你一個item佔了500px,它不能給你縮小吧。
但是這樣設置出來的效果是這樣的| #1##2##3##4##5##6##7#|
那,假如想各個item間隔均勻怎麼辦?就是|#1#2#3#4#5#6#7#|這樣的效果
還在修煉中,淘寶是這樣的,據說開源了,有空去看看。

邏輯部分

思路

  1. 頂部時間
    這個簡單,選中後將選中的時間顯示上去即可;
    需求:需要recyclerView記住選中位置的年、月、日(selectedYear、selectedMonth、selectedDay)
  2. 菜單欄
    • 左箭頭,上一月
      邏輯與右鍵頭類似,參考右鍵頭

    • 中間顯示當前年、月
      這個也簡單,左右箭頭翻頁時動態改變當前展示的年、月
      需求:需要recyclerView記住當前展示的年、月(requestYear、requestMonth)

    • 右鍵頭,下一月
      這裏通過Calendar類獲取時間,通過roll方法設置需要顯示的時間。
      類初始化時設置一個全局變量Calendar now = Calendar.getInstance();

      然後是點擊右鍵頭的代碼(month+1是因爲Calendar類獲得月份範圍是0-11)

      if(now.get(Calendar.MONTH)==11){
                  now.roll(Calendar.YEAR,1);
              }
              now.roll(Calendar.MONTH,1);
              int year = now.get(Calendar.YEAR);
              int month = now.get(Calendar.MONTH)+1;
              tv_year_month.setText(context.getString(R.string.date_picker_year_month,year,month));
              myAdapter.setRequestYear(year);
              myAdapter.setRequestMonth(month);
              initData();
              myAdapter.notifyDataSetChanged();
      
  3. 日曆主體
    看起來難做起來容易,首先獲得當前年、月、日;
    然後
    	now.set(Calendar.DATE,1);  //設置爲當月第一天
    	firstWeekday = now.get(Calendar.DAY_OF_WEEK);  //獲取第一天星期幾,假如是2,就是星期一
        now.roll(Calendar.DATE,-1);            //這個月第一天倒退一天
        dayCount =now.get(Calendar.DATE);              //獲取這個月總天數
        ```
    

然後新建一個List<Integer>數組;
先填入firstWeekday-1個-1,再依次填入1、2、…到dayCount
然後recyclerView新建適配器,設置一列顯示7個

int thisDay = list.get(position);			//當前遍歷的日期
if(lthisDay>0){									//如果不是-1
	item.setText(String.valueOf(thisDay));		//設置item顯示值爲這個日期,注意要轉String
	if(thisDay<CurrentDay&& requestMonth <= currentMonth && requestYear <= currentYear){		//如果這一天在今天之前,顯示灰色
	item.setTextColor(xxx);
	}else{
	item.setTextColor(xxx);顯示黑色
	item.setOnClickListener(xxx);設置點擊事件
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章