當前位置:
首頁 > 最新 > 自定義View之手動打造「流式布局」

自定義View之手動打造「流式布局」

記得兩周前分析過View載入的源碼,但是之後沒寫自定義View,今天抽出時間寫一篇文章,來手把手打造一款「流式布局」。這裡不是羅列代碼,是一步步按照筆者的思路去實現每一個細節。看完覺得有幫助的朋友可以點個贊,或者打個賞~

我們先來看看要實現什麼樣子的功能:

GIF/1K

首先,自定義一個View類繼承自ViewGroup,起名FlowLayout,然後把架子搭建起來:

由於注釋寫的非常的清晰,不再費文章。

然後開始布局測量onMeasure()的書寫:

通過父親對孩子的期望模式,來設置自己的寬高模式,而由於ViewGroup類型還擁有孩子,所以要通過for循環來測量自己的孩子(源碼就是這麼操作的)。

如下:

然後開始考慮換行,什麼時候換行呢?

首先,要確定下行高和行寬

計算方式如下:

代碼如下:

測量了孩子控制項和自己的大小之後,開始對控制項進行布局的擺放:

在布局之前,我們要知道l、t、r、b的意義:

由於在layout的時候,還是要拿到每一個孩子,對每一個孩子都單獨設置它的位置。每個孩子的位置擺放要知道幾個值:當前控制項的左邊距、left、top、right、bottom值,每個孩子的這些值都不盡相同。比如說:要擺放第一行的第一個控制項應該知道第一個控制項的left為0+它的左邊距值,right為left+控制項測量寬度+它的右邊距,top為當前的高度0+它的上邊距,bottom為它的top+控制項測量高度+距離下邊距;第一行的第二個控制項left=第一個控制項的左邊距+第一個控制項的寬度+第一個控制項的右邊距(此時記錄下來該值記為curLeft)+第二個控制項的左邊距,top=當前的行高0+上邊距,bottom=top+控制項測量高度+下邊距,right=left+測量的控制項寬度。以此類推。因此需要有一個變數記錄當前的left和top分別記為curLeft,curTop:

因此想辦法在onMeasure的時候就存起來每一行的高度以及每一行有多少個控制項,這樣才可以動態的計算:

那麼測量的代碼就如下:

代碼注釋的也很清楚。只要記得沒測量一個控制項之後curLeft都要改變值;且沒一行改變curLeft都要複位,以及此時curTop也要改變值即增加一行的高度。

那麼具體的存view和行高的位置還是在onMeasure的時候:

下面介紹該如何存:

首先要明確存什麼:

1、存每一行的高度

2、存每一行的控制項

3、存每一行

其次明確何時存:

1、在換行的時候存。第一行換到第二行的時候,存儲第一行的高度;第二行換到第三行的時候,存儲第二行的高度;依次類推。

2、在沒換行前存儲該行的每一個控制項。換行的時候要創建下一行的集合用於存儲下一行的孩子控制項。並在剛換行的時候存儲當前的孩子控制項,因為此時換行的控制項是下一行的第一個控制項。

3、每一次換行的時候,都要存儲每一行的集合。跟存儲高度一致。

那麼就把代碼實現出來:

1、

2、

3、

此時運行程序:

好像是結束了,但是此時是有問題的。因為布局中我是加了16個TextView,而這裡只是展示了12個TextView!!是最後一行沒有布局上去吧!

相信你已經知道哪裡的原因:

在我們的第1問的時候,

1、在換行的時候存。第一行換到第二行的時候,存儲第一行的高度;第二行換到第三行的時候,存儲第二行的高度;依次類推。

3、每一次換行的時候,都要存儲每一行的集合。跟存儲高度一致。

這裡是有問題的,因為都是在換行的時候才去存上一行的信息。那麼如果此時是最後一行,就不會存儲最後一行的高度,也不會把最後一行集合添加到外層存儲的集合。因此要做一個校驗,如果是最後一行,也要把高度和最後一行的ciew集合添加到外層集合中去。

因此,再加個判斷:

此時運行:

這個時候流式布局就開發完畢了。

然後,我們在自定義的View裡面再加入點擊事件,點擊每一個item都有點擊事件。在自定義View裡面添加回調介面:

這樣就可以暴露給外界使用我們的自定義View了。使用起來跟使用系統的差不多如下在Activity中的使用:

在這裡我只是列印了一條土司,當然你可以任意發揮去做任何事情,比如跳轉到指定的頁面,去條RN頁,等等...此時運行程序,就是開頭要實現的效果了。

這樣,一款自定義的流式布局就實現完成了,覺得可以記得手動點贊或者給個讚賞哦,你的支持,是筆者創作的動力,寫好每一篇高質量的文章。

歡迎關注,歡迎投稿。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 codeHoward 的精彩文章:

TAG:codeHoward |