CalendarListView 日歷列表

概述:


聽(tīng)過(guò)PullToRefreshListView,聽(tīng)過(guò)PinnedSectionListView,那你應(yīng)該沒(méi)聽(tīng)過(guò)CalendarListView,什么是CalendarListView呢畜号,ListView和Calendar扯上什么關(guān)系呢,我們先來(lái)看下Demo(動(dòng)畫(huà)效果會(huì)稍微有點(diǎn)卡頓,真實(shí)效果會(huì)比較流暢认罩,大家可以到我GitHub下載apk自己試用一下,效果還不錯(cuò)!)续捂。

CalendarListView Demo

CalendarListView 是一個(gè)ListView 和 CalendarView 結(jié)合并互相聯(lián)動(dòng)的控件垦垂,日歷可以伸縮擴(kuò)展宦搬,列表可以上拉下沉, 日歷的選擇會(huì)讓ListView 滑動(dòng)到指定的位置劫拗,ListView的滑動(dòng)同時(shí)也會(huì)帶動(dòng)日歷滑到指定位置并能同時(shí)自動(dòng)切換月份间校。如果我們的應(yīng)用涉及到聊天記錄、筆記页慷、訂單記錄憔足、天氣、日?qǐng)?bào)等和時(shí)間關(guān)系比較緊的業(yè)務(wù)場(chǎng)景酒繁,這樣的控件要比簡(jiǎn)單的ListView 來(lái)得更清晰一些滓彰,也更炫一些。如果你喜歡欲逃,可以先收藏很多業(yè)務(wù)場(chǎng)景都可以使用找蜜。

GitHub:https://github.com/Kelin-Hong/CalendarListView

功能簡(jiǎn)介:


可以參照上面的動(dòng)畫(huà),我安裝上面演示的順序說(shuō)明:
1稳析、CalendarListView 的上部分是常規(guī)的日歷模塊洗做,在日歷不收縮的情況下上下滑動(dòng)可以切換月份
2、在日歷不收縮的情況彰居,選擇日歷某一天诚纸,ListView的滑到指定日期的那一條。
3陈惰、在日歷不收縮的情況畦徘,選擇日歷某一天,選完之后抬闯,把ListView往上拉井辆,這時(shí)候會(huì)根據(jù)日歷選中日期(紅色框)的高度,計(jì)算出日歷的滑動(dòng)速率溶握,從而使整體滑到頂部的時(shí)候杯缺,日歷日期選中的那一行是可見(jiàn)的。
4睡榆、在日歷收縮的情況下萍肆,按住日歷往下拉,這時(shí)候和上面一樣經(jīng)過(guò)計(jì)算胀屿,使控件能夠平滑的展開(kāi)塘揣。
5、在日歷執(zhí)行展開(kāi)或者收縮過(guò)程中宿崭,用手在拖動(dòng)中亲铡,如果拖動(dòng)的距離超過(guò)一半放手了,會(huì)有動(dòng)畫(huà)執(zhí)行剩下的下滑或者上拉操作,如果拖動(dòng)沒(méi)有超過(guò)一半奖蔓,會(huì)自動(dòng)回到原來(lái)的位置琅摩。
6、在日歷收縮的情況下锭硼,滑動(dòng)ListView,這時(shí)候日期當(dāng)前ListView的section的日期變化了蜕劝,那么日歷會(huì)自動(dòng)選中當(dāng)前pin住的那個(gè)header的日期檀头,ListView上下滑動(dòng)都會(huì)牽動(dòng)日歷日期的變更(日歷會(huì)上下滑動(dòng)同時(shí)選中header的日期)
7、ListView 往下滑岖沛,到底的時(shí)候會(huì)自動(dòng)觸發(fā)LoadMore操作暑始,當(dāng)從1月份滑到二月份的時(shí)候,日歷會(huì)自動(dòng)切換2月份同時(shí)選中指定的日期婴削。
8廊镜、ListView 往上滑,到最頂部時(shí)候會(huì)自動(dòng)觸發(fā)Refresh操作唉俗,當(dāng)從1月份滑到去年12月份的時(shí)候嗤朴,日歷會(huì)自動(dòng)切換到去年12月份同時(shí)選中指定的日期。
9虫溜、ListView 快速滑動(dòng)試雹姊,日歷跟隨的日期仍能不會(huì)錯(cuò)
10、在日歷收縮的情況衡楞,選擇日歷某一天吱雏,ListView的依然滑到指定日期的那一條。

如何使用


compile 'com.kelin.mvvmlight:library:1.0.0'

CalendarListView 接口的設(shè)計(jì)使得用戶完全可以定制想要的UI和各種響應(yīng)的事件的支持

1瘾境、自定義CalendarView的樣式(在小格子里添加價(jià)格歧杏,tag,圖標(biāo)等)

//繼承BaseCalendarItemModel添加你想要的額外的字段迷守,比較價(jià)格犬绒,是否收藏,數(shù)量等
public class CustomCalendarItemModel  extends BaseCalendarItemModel{     
   //這一天有多少條數(shù)據(jù)
   private int count;
   //是否收藏(如Demo 日歷上有沒(méi)有愛(ài)心)
   private boolean isFav;
   //get set
   ...
   ...
}
// 繼承BaseCalendarItemAdapter<T> (T 為你自定義的Model extendsBaseCalendarItemModel)盒犹,
// 重寫(xiě) getView方法自定義CalendarView Item 的樣式和數(shù)據(jù)
public class CalendarItemAdapter extends BaseCalendarItemAdapter<CustomCalendarItemModel>{
    //date 是時(shí)間懂更,樣式“yyyy-MM-dd”
    @Override
    public View getView(String date, CustomCalendarItemModel model, View convertView, ViewGroup parent) {
        //也可以從dayModelList 根據(jù)date獲取指定時(shí)間的model(dayModelList是基類的變量)  CustomCalendarItemModel model = dayModelList.get(date);
        ....
        ViewGroup view = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.custom_calendar_item, null);
        TextView dayNum = (TextView)  view.findViewById(R.id.day_num);
        dayNum.setText(model.getDayNumber());
        ....
        //從model里面獲取數(shù)據(jù)自定義想要的UI
        ....
        ....
   }
}

注:如果不需要再日歷頁(yè)面添加自定義的元素,也可以直接使用BaseCalendarItemAdapter 急膀,這樣日歷的視圖只會(huì)有日期沮协,依然是可用的。

2卓嫂、自定義ListView的樣式慷暂,和傳統(tǒng)的BaseAdapter 差不多,重寫(xiě)getSectionHeaderView自定義SectionHeader的樣式,重寫(xiě)getItemView自定義每個(gè)Item的樣式行瑞。

public class ListItemAdapter extends BaseCalendarListAdapter<ListModel> {
    //date 是時(shí)間奸腺,樣式“yyyy-MM-dd”
    @Override
    public View getSectionHeaderView(String date, View convertView, ViewGroup parent) {
       List<ListModel> modelList = dateDataMap.get(date);
       .....
       .....//根據(jù)數(shù)據(jù)模型自定義ListView SectionHeader的樣式
       .....
    }
   //date 是時(shí)間,樣式“yyyy-MM-dd”
    @Override
    public View getItemView(ListModel model,String date, int pos, View convertView, ViewGroup parent) {
      //通過(guò)基類BaseCalendarListAdapter的成員變量dateDataMap可以獲取當(dāng)前date的包含的數(shù)據(jù)列表
      //List<ListModel> modelList = dateDataMap.get(date);
      //model = modelList.get(pos) 也可以獲取model
      
      .....
      .....//根據(jù)數(shù)據(jù)模型model自定義ListView Item的樣式
      .....
   }
}

3血久、初始化CalendarListView 并且設(shè)置CalendarItemAdapter和ListItemAdapter

<com.kelin.calendarlistview.library.calendar.CalendarListView   
   android:id="@+id/calendar_listview"    
   android:layout_width="match_parent"    
   android:layout_height="match_parent">
</com.kelin.calendarlistview.library.calendar.CalendarListView>
//在onCreate中分別創(chuàng)建兩個(gè)Adapter的實(shí)例突照,并且設(shè)置到CalendarListView里面
@Override
protected void onCreate(Bundle savedInstanceState) {
 //獲取calendarListView
 calendarListView = (CalendarListView) findViewById(R.id.calendar_listview);

 //聲明CalendarView和ListView的Adapter,分別為上面1氧吐、2步自定義的樣式的Adapter
 listItemAdapter = new ListItemAdapter(this);
 calendarItemAdapter = new CalendarItemAdapter(this);

 //給calendarListView設(shè)置Adapter
 calendarListView.setCalendarListViewAdapter(calendarItemAdapter, listItemAdapter);

}

4讹蘑、去服務(wù)器獲取日歷和列表的數(shù)據(jù)(建議接口按月份來(lái))獲取每個(gè)月份的數(shù)據(jù),在獲取完數(shù)據(jù)更新日歷和列表

  • 對(duì)于CalendarView的數(shù)據(jù)更新
private void onCalendarDataLoadFinish(List<Data> datas){
    ....
    ....
    //calendarItemAdapter.getDayModelList()可以獲取當(dāng)前月份的所有數(shù)據(jù)列表
    //它是一個(gè)TreeMap<String, T>筑舅,key是“yyyy-MM-dd”座慰,value 是當(dāng)天的數(shù)據(jù)模型
    TreeMap<String, CustomCalendarItemModel> dateMap=calendarItemAdapter.getDayModelList();
    ....
    //獲取指定日期的Model,date的格式是yyyy-MM-dd
    CustomCalendarItemModel customCalendarItemModel = dateMap.get(date);
    //更新數(shù)據(jù)模型的數(shù)據(jù)
    customCalendarItemModel.setXXX(data.getXXX());
   ....
   ....
   //通知日歷更新UI
   calendarItemAdapter.notifyDataSetChanged();
}
  • 對(duì)于ListView的數(shù)據(jù)更新
 //建議聲明一個(gè)TreeMap<String, List<ListModel>>的成員變量用來(lái)保持每一天下面的數(shù)據(jù)列表
//key:date "yyyy-mm-dd" format.
private TreeMap<String, List<ListModel>> listTreeMap = new TreeMap<>();

private void onListDataLoadFinish(List<Data> datas){
   ....
   ....
  for(Data item:datas) {
     //獲取數(shù)據(jù)的日期
     String day=item.getDate();
    //給listTreeMap 添加數(shù)據(jù)
     if (listTreeMap.get(day) != null) {    
         List<NewsService.News.StoriesBean> list = listTreeMap.get(day);    
         list.add(i);
      } else {    
         List<NewsService.News.StoriesBean> list = new ArrayList<NewsService.News.StoriesBean>();    
         list.add(i);   
         listTreeMap.put(day, list);
     }
  }
 ....
 ....
 //更新數(shù)據(jù),通知更新UI
 listItemAdapter.setDateDataMap(listTreeMap);
 listItemAdapter.notifyDataSetChanged();
}

5翠拣、CalendarView的事件支持

  • 日期選擇
calendarListView.setOnCalendarViewItemClickListener(new CalendarListView.OnCalendarViewItemClickListener() {   
     //具體參數(shù)看注釋版仔,寫(xiě)得比較詳細(xì)
     @Override    
     public void onDateSelected(View View, String selectedDate, int listSection) {   
     //do something....
     }
});
  • 月份改變
calendarListView.setOnMonthChangedListener(new CalendarListView.OnMonthChangedListener() {    
       @Override    
       public void onMonthChanged(String yearMonth) {
       //yearMonth:"yyyy-MM-dd"
       
       }
});
  • 下拉刷新,上拉加載更多
calendarListView.setOnListPullListener(new CalendarListView.onListPullListener() {    
    @Override    
    public void onRefresh() {
          
    }    
    @Override    
    public void onLoadMore() {
 
    }
});

6误墓、CalendarView的選中框樣式顏色蛮粮、上方的week bar 的樣式都是支持自定義的。

備注


1谜慌、控件部分交互有些小復(fù)雜蝉揍,可能存在一些Bug,歡迎issue和PR畦娄!
2又沾、源碼涉及較多事件分發(fā)的處理,如果你有看過(guò)我的另一篇文章《圖解Android事件分發(fā)機(jī)制》熙卡,那么源碼應(yīng)該是比較好的實(shí)踐杖刷,可以去讀一下。
3驳癌、任何控件上的問(wèn)題或者使用上的問(wèn)題滑燃,可以給我留言或私信。
4颓鲜、最后表窘,喜歡可以收藏哦!O(∩_∩)O~~

![Uploading calendarListView_247688.jpg . . .]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末甜滨,一起剝皮案震驚了整個(gè)濱河市乐严,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌衣摩,老刑警劉巖昂验,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡既琴,警方通過(guò)查閱死者的電腦和手機(jī)占婉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)甫恩,“玉大人逆济,你說(shuō)我怎么就攤上這事』腔” “怎么了纹腌?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)滞磺。 經(jīng)常有香客問(wèn)我,道長(zhǎng)莱褒,這世上最難降的妖魔是什么击困? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮广凸,結(jié)果婚禮上阅茶,老公的妹妹穿的比我還像新娘。我一直安慰自己谅海,他們只是感情好脸哀,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著扭吁,像睡著了一般撞蜂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上侥袜,一...
    開(kāi)封第一講書(shū)人閱讀 52,262評(píng)論 1 308
  • 那天蝌诡,我揣著相機(jī)與錄音,去河邊找鬼枫吧。 笑死浦旱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的九杂。 我是一名探鬼主播颁湖,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼例隆!你這毒婦竟也來(lái)了甥捺?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤镀层,失蹤者是張志新(化名)和其女友劉穎涎永,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡羡微,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年谷饿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妈倔。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡博投,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盯蝴,到底是詐尸還是另有隱情毅哗,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布捧挺,位于F島的核電站虑绵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏闽烙。R本人自食惡果不足惜翅睛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望黑竞。 院中可真熱鬧捕发,春花似錦、人聲如沸很魂。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)遏匆。三九已至法挨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間幅聘,已是汗流浹背坷剧。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留喊暖,地道東北人惫企。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像陵叽,于是被迫代替她去往敵國(guó)和親狞尔。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容