Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android簡單實現自定義流式布局的方法

Android簡單實現自定義流式布局的方法

編輯:關於Android編程

本文實例講述了Android簡單實現自定義流式布局的方法。分享給大家供大家參考,具體如下:

首先來看一下 手淘HD - 商品詳情 - 選擇商品屬性 頁面的UI

商品有很多尺碼,而且展現每個尺碼所需要的View的大小也不同(主要是寬度),所以在從服務器端拉到數據之前,展現所有尺碼所需要的行數和每一行的個數都無法確定,因此不能直接使用GridView或ListView。

如果使用LinearLayout呢?

一個LinearLayout只能顯示一行,如果要展示多行,則每一行都要new一個LinearLayout出來,而且還必須要計算出每一個LinearLayout能容納多少個尺碼對應的View,實現起來也會比較復雜。

其實要實現這個功能,只需要借鑒一下CSS3的flex-box 就可以了。

要實現一個Android版本的flexbox,原理非常簡單,為了與Android的命名規范保持一致,我們稱之為FlowLayout。

1. 首先新建一個FlowLayout類,繼承自ViewGroup
2. 在onMeasure中根據 child views 計算出FlowLayout高度
3. 在onLayout中對child views 的進行布局(layout)

下面只列出了最核心的代碼片段,完整代碼已經放到Github上-AndroidFlowLayout,歡迎fork。

在onMeasure中計算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();
  // 計算當前行的高度(當前行所有子View中最高的那個)
  lineHeight = Math.max(childHeight, lineHeight);
  // 把當前child view放到上一個child view的右邊,如果放不下,則換行
  if (childLeft + childWidth + paddingRight > myWidth) {
    childLeft = paddingLeft;
    childTop += mVerticalSpacing + lineHeight;
    lineHeight = childHeight;
  } else {
    childLeft += childWidth + mHorizontalSpacing;
  }
}
int wantedHeight = childTop + lineHeight + paddingBottom;
// 計算FlowLayout所需要高度
setMeasuredDimension(myWidth, resolveSize(wantedHeight, heightMeasureSpec));

在onLayout中對child views進行布局

代碼與onMeasure非常類似,只需要根據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;
  }
  // 關鍵代碼
  childView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);
  childLeft += childWidth + mHorizontalSpacing;
}

完整版代碼已經放到Github-FlowLayout,打出來的aar包已經上傳到了bintray,使用方式非常簡單,只需要在項目(project)對應的build.gradle中添加一條dependency即可。

compile 'com.liangfeizc:flowlayout:1.0.0@aar'

把aar包上傳到 jCenter

具體做法可參考 publishing gradle android library to jcenter
打包腳本可參考 flowlayout/build.gradle

更多關於Android相關內容感興趣的讀者可查看本站專題:《Android布局layout技巧總結》、《Android視圖View技巧總結》、《Android操作XML數據技巧總結》、《Android編程之activity操作技巧總結》、《Android資源操作技巧匯總》、《Android文件操作技巧匯總》、《Android操作SQLite數據庫技巧總結》、《Android操作json格式數據技巧總結》、《Android數據庫操作技巧總結》、《Android編程開發之SD卡操作方法匯總》、《Android開發入門與進階教程》及《Android控件用法總結》

希望本文所述對大家Android程序設計有所幫助。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved