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* 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(默认)即可。