超簡單android自定義控件流式布局SimpleFlowLayout

技術(shù)的進(jìn)步,總是由需求推動的 ——安卓君

1、前言

流式布局是app開發(fā)中必不可少的布局方式,例如照片墻,篩選標(biāo)簽等等?;旧厦總€app里面都可以看到這樣的布局,但是android API中并沒有提供實現(xiàn)流式布局方式的控件,因此自己實現(xiàn)一個流式布局的控件就非常有必要了。本文分享筆者實現(xiàn)FlowLayout思考過程,希望能夠拋轉(zhuǎn)引玉,為大家提供一個新的思路,文章末尾有代碼鏈接。

2、效果

下面是效果圖:

SimpleFlowLayout示例圖

3、分析

實現(xiàn)自定義控件肯定要從View的繪制原理開始思考,關(guān)于View的繪制原理這里就不做介紹了。首先可以確定的是我們要實現(xiàn)的是一個ViewGroup,多個標(biāo)簽(子控件(View)) 被放置到ViewGroup中。所以要實現(xiàn)的有:

  • 1.測量父控件(ViewGroup)的大小
  • 2.放置子控件(View)

體現(xiàn)在代碼中就是實現(xiàn)父控件的兩個方法:

  • 1.onMeasure()
  • 2.onLayout()

3.1、計算父控件的寬高

3.1.1 計算父控件寬度

流式布局寬度一般都是指定的,match_parent 或者具體數(shù)值。測量模式為MeasureSpec.EXACTLY,可以通過MeasureSpec.getSize(widthMeasureSpec);方法獲取。如果不是指定寬度,就無法換行擺放子控件,流式布局也就不存在了。

3.1.2 計算父控件的高度

結(jié)合效果圖看,父控件的高度由子控件行數(shù)決定的,本文假設(shè)每個子控件高度一致,行間距一致,間隔一致。

父控件高度 = paddingTop + paddingBottom + 行高*行數(shù) + 行間距*(行數(shù) - 1)
計算高度

可以看到計算高度的關(guān)鍵是\color{red}{行數(shù)}\,所以剩下的問題就是如何計算行數(shù)。

如何計算行數(shù)?

計算行數(shù)的關(guān)鍵在于知道什么時候換行,我們先看看效果圖每一行子控件實際占據(jù)的寬度


計算寬度

在FlowLayout中,一行子控件實際占據(jù)寬度為

行寬度 = 子控件寬度 + 間隔 ... (間隔數(shù)比子控件少一個)

所以我們可以很容易得出這樣一個換行條件

paddingLeft + 行寬度 +  下一個子控件的寬度 + paddingRight > 父控件寬度

我們可以通過for循環(huán)遍歷子控件集合計算出總行數(shù),當(dāng)我們得出行數(shù)時,就可以計算出父控件的高度,測量寬高的工作就完成了。

3.2 放置子控件

放置子控件,最終調(diào)用

layout(int l, int t, int r, int b)

所以只要得到每個子控件的位置信息就可以最終展現(xiàn)出流式布局,很多人在實現(xiàn)FlowLayout時,會在這里重新測量再計算子控件的位置,我覺得比較繁瑣,而且重復(fù)的測量也耗費資源。我想到,在onMeasure()方法中,需要遍歷子控件計算寬高,那么為什么不在遍歷的時候,計算出每個子控件的位置,再通過setTag()方法把位置信息賦值給子控件呢?那樣的話在執(zhí)行onLayout()方法,放置子控件的時候,就可以通過遍歷子控件,getTag() 得到每個子控件的位置信息,就可以實現(xiàn)所有子控件的放置了。

如何計算每個子控件的位置?

計算子控件位置

如上圖所示,只要計算出子控件的寬高,我們很容易就能得出left,top,bottom,right值。

4.實現(xiàn)單選和多選

如何實現(xiàn)子控件的單選功能?

可以借鑒RadioGroup實現(xiàn)原理,也可以換一種思路,直接繼承RadioGroup就可以實現(xiàn)單選的功能,添加RadioButton作為子控件,相當(dāng)于把RadioGroup改造成具有流式布局功能的控件。

如何實現(xiàn)子控件的多選功能?

如果添加的子控件都是CheckBox,就可以實現(xiàn)多選的功能。

5.總結(jié)

FlowLayout算不上非常復(fù)雜的控件,原理也很簡單,一個是計算父容器的寬高,一個是獲取子控件的位置。本文從筆者實際業(yè)務(wù)出發(fā),行間距,間隔都是在自定義屬性中設(shè)置的固定值,實現(xiàn)起來也簡單。自認(rèn)為本文特別之處在于,提供新的思路,讓流式布局實現(xiàn)起來更簡單優(yōu)雅

在測量子控件時,計算每個控件的位置,并設(shè)置到子控件

本文主要分享思考過程、實現(xiàn)方法,不能說多完美,希望能帶給大家一點啟發(fā)。作者歡迎評論,探討!
源碼地址:https://github.com/f1mert/SimpleFlowLayout 歡迎點擊!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容