概述
由于項(xiàng)目需要诬像,我們需要一個(gè) 可以橫向滾動(dòng)的跪腹,又可以豎向滾動(dòng)的 表格。而且又要考慮大數(shù)據(jù)量(行)的展示視圖开伏。經(jīng)過(guò)幾天的研究終于搞定膀跌,做了一個(gè)演示。
效果圖:
![](http://upload-images.jianshu.io/upload_images/2044033-5ee3cab9f37c4ef6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
設(shè)計(jì)圖
- 第一列固灵,是固定的捅伤,比如我們第一列一般顯示編號(hào)序號(hào)
- 其它列,可滾動(dòng)
- 在其它列滾動(dòng)時(shí)巫玻,列頭(header)也隨之滾動(dòng)
思路
上下滾動(dòng)直接使用 listView來(lái)實(shí)現(xiàn)丛忆。
-
左右滾動(dòng)使用HorizontalScrollView,來(lái)處理滾動(dòng)。我寫一個(gè)類MyHScrollView繼承 自它仍秤。
2.1 . ListView里的每行(row)分為 兩部分熄诡,不滾動(dòng)的和可滾動(dòng)的區(qū)域。比如本demo的第一列诗力,就是靜態(tài)的凰浮。而后面的所有列都是可以滾動(dòng)的。
2.2. 我不想自己計(jì)算滾動(dòng)的距離姜骡,因?yàn)檫€要處理越界导坟,坐標(biāo)等等。于是我使用 OnTouch事件來(lái)處理圈澈。于是我們必須搞懂OnTouch的運(yùn)行機(jī)制惫周。了解 請(qǐng)google it.
2.3. 列頭 (顯示列名的那一行)是固定的,不會(huì)上下滾動(dòng) 康栈。但可以左右滾動(dòng)递递。而且它在左右滾動(dòng)時(shí),所有的 數(shù)據(jù)行(row) ,都要與其一起左右滾動(dòng)啥么。那么我們需要監(jiān)聽 列頭 (控件)的滾動(dòng)變化消息(事件)登舞,并將消息廣播給所有的 數(shù)據(jù)行。這些數(shù)據(jù)行收到消息后悬荣,調(diào)整自己的滾動(dòng)條位置以保持和 列頭 的滾動(dòng)距離一致菠秒。
-
那么整個(gè)流程基本是這樣的。
3.1, 捕獲 列頭(容器控件氯迂,包含固定和可滾動(dòng)控件)的 onTouch事件(拖動(dòng)事件)践叠,不處理言缤。而分發(fā)給 “列頭里的 可滾動(dòng)部分的控件”,該控件是一個(gè)HorizontalScrollView的 子類禁灼, 當(dāng)它收到這些 拖動(dòng)事件時(shí)管挟,就產(chǎn)生了固定的效果
3.2. 捕獲 數(shù)據(jù)行 區(qū) 的控件(該控件其實(shí)就是ListView控件 )的OnTouch事件,不處理弄捕,同樣分發(fā)給 “列頭里的 可滾動(dòng)部分的控件”僻孝。 這兩步,就完成了一個(gè)小效果守谓,點(diǎn)擊表 格的頭部和體部都能移動(dòng)(滾動(dòng))行穿铆。
3.3. 我寫了一個(gè) HorizontalScrollView的子類,重載 onScrollChanged 方法分飞,該方法在 滾動(dòng)之后執(zhí)行悴务,相當(dāng)于“滾動(dòng)后的事件”,我寫了一個(gè)觀察者(設(shè)計(jì)模式)的類譬猫。每次 滾動(dòng)后,都通知給 觀察者羡疗。觀察者再通知給它的訂閱者(那些需要同時(shí)滾動(dòng)的行里面的 滾動(dòng)控件)染服。
3.4. 當(dāng)ListView創(chuàng)建行時(shí),讓這些行都訂閱 上一步 的觀察者叨恨。當(dāng) 收到消息后柳刮,調(diào)整自身的滾動(dòng)條位置以保持和 列頭 的滾動(dòng)條位置一致。
代碼比較多痒钝,就不貼了秉颗。請(qǐng)下載: 源代碼下載。