import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; public class LineBreakLayout extends LinearLayout { private final static String TAG = "LineBreakLayout"; private final static int VIEW_MARGIN = 8; public LineBreakLayout(Context context) { super(context); } public LineBreakLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public LineBreakLayout(Context context, AttributeSet attrs) { super(context, attrs); } @Override protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) { final int count = getChildCount(); Log.d(TAG, "changed = " + arg0 + " left = " + arg1 + " top = " + arg2 + " right = " + arg3 + " botom = " + arg4 + ", childcount = " + count); int row = 0;// which row lay you view relative to parent int lengthX = 0; // right position of child relative to parent int lengthY = 0; // bottom position of child relative to parent for (int i = 0; i < count; i++) { final View child = this.getChildAt(i); child.measure(0, 0); int width = child.getMeasuredWidth(); int height = child.getMeasuredHeight(); lengthX += width + VIEW_MARGIN; lengthY = row * (height + VIEW_MARGIN) + VIEW_MARGIN + height; // if it can't drawing on a same line , skip to next line if (lengthX > arg3 - arg1) { lengthX = width + VIEW_MARGIN; row++; lengthY = row * (height + VIEW_MARGIN) + VIEW_MARGIN + height; } child.layout(lengthX - width, lengthY - height, lengthX, lengthY); Log.d(TAG, "child i = " + i + ", width = " + width + ", height = " + height + ", lengthX = " + lengthX + ", lengthY = " + lengthY); } ViewGroup.LayoutParams params = getLayoutParams(); params.height = lengthY + VIEW_MARGIN; } }