Android開發之自動換行LinearLayout
阿新 • • 發佈:2019-01-22
Android開發中,很多人會遇到滿行就自動換到下一行的介面需求,而Android自帶的LinearLayout佈局自能橫排或者豎排,不夠顯示就加ScrollView,橫豎混排就不行了。這裡給大家分享一個可以實現自動換行的LinearLayout。
import java.util.Hashtable; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.widget.LinearLayout; /** * 自動換行的LinearLayout * @author idengpan * */ @SuppressWarnings({ “unchecked”,”rawtypes” }) public class AutoNextLineLinearlayout extends LinearLayout { int mLeft, mRight, mTop, mBottom; Hashtable map = new Hashtable(); public AutoNextLineLinearlayout(Context context) { super(context); } public AutoNextLineLinearlayout(Context context, int horizontalSpacing, int verticalSpacing) { super(context); } public AutoNextLineLinearlayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int mWidth = MeasureSpec.getSize(widthMeasureSpec); int mCount = getChildCount(); int mX = 0; int mY = 0; mLeft = 0; mRight = 0; mTop = 5; mBottom = 0; int j = 0; View lastview = null; for (int i = 0; i < mCount; i++) { final View child = getChildAt(i); child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); // 此處增加onlayout中的換行判斷,用於計算所需的高度 int childw = child.getMeasuredWidth(); int childh = child.getMeasuredHeight(); mX += childw; // 將每次子控制元件寬度進行統計疊加,如果大於設定的高度則需要換行,高度即Top座標也需重新設定 Position position = new Position(); mLeft = getPosition(i – j, i); mRight = mLeft + child.getMeasuredWidth(); if (mX >= mWidth) { mX = childw; mY += childh; j = i; mLeft = 0; mRight = mLeft + child.getMeasuredWidth(); mTop = mY + 5; // PS:如果發現高度還是有問題就得自己再細調了 } mBottom = mTop + child.getMeasuredHeight(); mY = mTop; // 每次的高度必須記錄 否則控制元件會疊加到一起 position.left = mLeft; position.top = mTop + 3; position.right = mRight; position.bottom = mBottom; map.put(child, position); } setMeasuredDimension(mWidth, mBottom); } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(0, 0); // default of 1px spacing } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int count = getChildCount(); for (int i = 0; i < count; i++) { View child = getChildAt(i); Position pos = (Position) map.get(child); if (pos != null) { child.layout(pos.left, pos.top, pos.right, pos.bottom); } else { Log.i(“MyLayout”, “error”); } } } private class Position { int left, top, right, bottom; } public int getPosition(int IndexInRow, int childIndex) { if (IndexInRow > 0) { return getPosition(IndexInRow – 1, childIndex – 1) + getChildAt(childIndex – 1).getMeasuredWidth() + 8; } return getPaddingLeft(); } }
用法和普通的LinearLayout類似,在XML佈局檔案中寫入這個自定義類的完整路徑,將android:orientation屬性指定為horizontal(預設)即可。