Android簡(jiǎn)單實(shí)現(xiàn)自定義流式布局的方法
本文實(shí)例講述了Android簡(jiǎn)單實(shí)現(xiàn)自定義流式布局的方法。分享給大家供大家參考,具體如下:
首先來看一下 手淘HD - 商品詳情 - 選擇商品屬性 頁(yè)面的UI

商品有很多尺碼,而且展現(xiàn)每個(gè)尺碼所需要的View的大小也不同(主要是寬度),所以在從服務(wù)器端拉到數(shù)據(jù)之前,展現(xiàn)所有尺碼所需要的行數(shù)和每一行的個(gè)數(shù)都無法確定,因此不能直接使用GridView或ListView。
如果使用LinearLayout呢?
一個(gè)LinearLayout只能顯示一行,如果要展示多行,則每一行都要new一個(gè)LinearLayout出來,而且還必須要計(jì)算出每一個(gè)LinearLayout能容納多少個(gè)尺碼對(duì)應(yīng)的View,實(shí)現(xiàn)起來也會(huì)比較復(fù)雜。
其實(shí)要實(shí)現(xiàn)這個(gè)功能,只需要借鑒一下CSS3的flex-box 就可以了。

要實(shí)現(xiàn)一個(gè)Android版本的flexbox,原理非常簡(jiǎn)單,為了與Android的命名規(guī)范保持一致,我們稱之為FlowLayout。
1. 首先新建一個(gè)FlowLayout類,繼承自ViewGroup
2. 在onMeasure中根據(jù) child views 計(jì)算出FlowLayout高度
3. 在onLayout中對(duì)child views 的進(jìn)行布局(layout)
下面只列出了最核心的代碼片段,完整代碼已經(jīng)放到Github上-AndroidFlowLayout,歡迎fork。
在onMeasure中計(jì)算FlowLayout的高度
// 遍歷所有的子View
for (int i = 0, childCount = getChildCount(); i < childCount; ++i) {
View childView = getChildAt(i);
// measure子View,并獲取它的寬度和高度
LayoutParams childLayoutParams = childView.getLayoutParams();
childView.measure(
getChildMeasureSpec(widthMeasureSpec, paddingLeft + paddingRight, childLayoutParams.width),
getChildMeasureSpec(heightMeasureSpec, paddingTop + paddingBottom, childLayoutParams.height));
int childWidth = childView.getMeasuredWidth();
int childHeight = childView.getMeasuredHeight();
// 計(jì)算當(dāng)前行的高度(當(dāng)前行所有子View中最高的那個(gè))
lineHeight = Math.max(childHeight, lineHeight);
// 把當(dāng)前child view放到上一個(gè)child view的右邊,如果放不下,則換行
if (childLeft + childWidth + paddingRight > myWidth) {
childLeft = paddingLeft;
childTop += mVerticalSpacing + lineHeight;
lineHeight = childHeight;
} else {
childLeft += childWidth + mHorizontalSpacing;
}
}
int wantedHeight = childTop + lineHeight + paddingBottom;
// 計(jì)算FlowLayout所需要高度
setMeasuredDimension(myWidth, resolveSize(wantedHeight, heightMeasureSpec));
在onLayout中對(duì)child views進(jìn)行布局
代碼與onMeasure非常類似,只需要根據(jù)child view的寬度和高度放到指定位置即可。
for (int i = 0, childCount = getChildCount(); i < childCount; ++i) {
View childView = getChildAt(i);
if (childView.getVisibility() == View.GONE) {
continue;
}
int childWidth = childView.getMeasuredWidth();
int childHeight = childView.getMeasuredHeight();
lineHeight = Math.max(childHeight, lineHeight);
if (childLeft + childWidth + paddingRight > myWidth) {
childLeft = paddingLeft;
childTop += mVerticalSpacing + lineHeight;
lineHeight = childHeight;
}
// 關(guān)鍵代碼
childView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
childLeft += childWidth + mHorizontalSpacing;
}
完整版代碼已經(jīng)放到Github-FlowLayout,打出來的aar包已經(jīng)上傳到了bintray,使用方式非常簡(jiǎn)單,只需要在項(xiàng)目(project)對(duì)應(yīng)的build.gradle中添加一條dependency即可。
compile 'com.liangfeizc:flowlayout:1.0.0@aar'
把a(bǔ)ar包上傳到 jCenter
具體做法可參考 publishing gradle android library to jcenter
打包腳本可參考 flowlayout/build.gradle
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android布局layout技巧總結(jié)》、《Android視圖View技巧總結(jié)》、《Android操作XML數(shù)據(jù)技巧總結(jié)》、《Android編程之a(chǎn)ctivity操作技巧總結(jié)》、《Android資源操作技巧匯總》、《Android文件操作技巧匯總》、《Android操作SQLite數(shù)據(jù)庫(kù)技巧總結(jié)》、《Android操作json格式數(shù)據(jù)技巧總結(jié)》、《Android數(shù)據(jù)庫(kù)操作技巧總結(jié)》、《Android編程開發(fā)之SD卡操作方法匯總》、《Android開發(fā)入門與進(jìn)階教程》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
- Android流式布局FlowLayout詳解
- Android流式布局實(shí)現(xiàn)歷史搜索記錄功能
- Android實(shí)現(xiàn)熱門標(biāo)簽的流式布局
- Java Swing組件布局管理器之FlowLayout(流式布局)入門教程
- Android自定義ViewGroup之實(shí)現(xiàn)FlowLayout流式布局
- Android 簡(jiǎn)單實(shí)現(xiàn)一個(gè)流式布局的示例
- Android自定義流式布局/自動(dòng)換行布局實(shí)例
- python GUI框架pyqt5 對(duì)圖片進(jìn)行流式布局的方法(瀑布流flowlayout)
- android流式布局onLayout()方法詳解
- Flexbox+ReclyclerView實(shí)現(xiàn)流式布局
相關(guān)文章
Android開發(fā)中的9個(gè)常見錯(cuò)誤和解決方法
這篇文章主要介紹了Android開發(fā)中的9個(gè)常見錯(cuò)誤和解決方法,這是Android開發(fā)中最常見的9個(gè)錯(cuò)誤,經(jīng)過各種各樣的整理,以及和熱心網(wǎng)友討論總結(jié)而來,需要的朋友可以參考下2015-01-01
Android Studio導(dǎo)入項(xiàng)目不支持的兩種解決方式
這篇文章主要介紹了Android Studio導(dǎo)入項(xiàng)目不支持的兩種解決方式,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
flutter PageView實(shí)現(xiàn)左右滑動(dòng)切換視圖
這篇文章主要為大家詳細(xì)介紹了flutter PageView實(shí)現(xiàn)左右滑動(dòng)切換視圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07
Kotlin高階函數(shù)reduce與fold使用實(shí)例
Kotlin的高階函數(shù)reduce和fold可以用來對(duì)集合進(jìn)行聚合操作。reduce函數(shù)將集合元素逐個(gè)累加,而fold函數(shù)則可以指定一個(gè)初始值進(jìn)行累加。這兩個(gè)函數(shù)在處理大數(shù)據(jù)集時(shí)非常有用2023-04-04
Android編程開發(fā)之EditText實(shí)現(xiàn)輸入QQ表情圖像的方法
這篇文章主要介紹了Android編程開發(fā)之EditText實(shí)現(xiàn)輸入QQ表情圖像的方法,涉及Android多媒體文件及EditText的相關(guān)操作技巧,需要的朋友可以參考下2015-12-12
基于RxJava框架實(shí)現(xiàn)獲取驗(yàn)證碼的輔助類
這篇文章主要為大家詳細(xì)介紹了基于RxJava框架實(shí)現(xiàn)獲取驗(yàn)證碼的輔助類,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06
Android編程實(shí)現(xiàn)泡泡聊天界面實(shí)例詳解(附源碼)
這篇文章主要介紹了Android編程實(shí)現(xiàn)泡泡聊天界面,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android泡泡聊天界面的窗體定義與功能實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
Android Gradle Build Error:Some file crunching failed, see l
這篇文章主要介紹了Android Gradle Build Error:Some file crunching failed, see logs for details解決辦法的相關(guān)資料,需要的朋友可以參考下2016-11-11
漂亮的Android音樂歌詞控件 仿網(wǎng)易云音樂滑動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了漂亮的Android音樂歌詞控件,仿網(wǎng)易云音樂滑動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01

