最近項目需求要寫一個類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#|這樣的效果
還在修煉中,淘寶是這樣的,據說開源了,有空去看看。
邏輯部分
思路
- 頂部時間
這個簡單,選中後將選中的時間顯示上去即可;
需求:需要recyclerView記住選中位置的年、月、日(selectedYear、selectedMonth、selectedDay) - 菜單欄
-
左箭頭,上一月
邏輯與右鍵頭類似,參考右鍵頭 -
中間顯示當前年、月
這個也簡單,左右箭頭翻頁時動態改變當前展示的年、月
需求:需要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();
-
- 日曆主體
看起來難做起來容易,首先獲得當前年、月、日;
然後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);設置點擊事件
}
}