之前项目遇到需要自动换行的linearlayout,当时没有实现出来,现在已经搞定,把它分享出来。
我用的是viewgroup写的,其实也可以用其他容器控件写,有需要的同学自己去扩展。
package com.example.test.auto.change.lines; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; /** * 自动换行ViewGroup */ public class AutoChangeLinesViewGroup extends ViewGroup { private final String TAG = "AutoChangeLinesViewGroup"; private final static int VIEW_MARGIN = 2; public AutoChangeLinesViewGroup(Context context) { super(context); // TODO Auto-generated constructor stub } public AutoChangeLinesViewGroup(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub } public AutoChangeLinesViewGroup(Context context, AttributeSet attrs,int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // TODO Auto-generated method stub Log.d(TAG, "changed ==== " + changed + " l == " + l + " t === " + t + " r == " + r + " b== " + b); int row = 0; int width = 0; int height = 0; if(changed){ final int count = getChildCount(); for(int i = 0; i < count; i++){ final View child = this.getChildAt(i); int measuredWidth = child.getMeasuredWidth(); int measuredHeight = child.getMeasuredHeight(); width += measuredWidth + VIEW_MARGIN; height = row * ( measuredHeight + VIEW_MARGIN ) + VIEW_MARGIN + measuredHeight; if(width > r){ width = measuredWidth + VIEW_MARGIN; if(width > r){ width = r - l ; } row ++; height = row * ( measuredHeight + VIEW_MARGIN ) + VIEW_MARGIN + measuredHeight; // 超出最大范围之后不绘制 child.layout(0, height - measuredHeight, width, height); }else { child.layout(width - measuredWidth, height - measuredHeight, width, height); } } } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub for(int i = 0 ; i < getChildCount() ; i ++){ final View childView = getChildAt(i); childView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }
此控件有一个问题,如果它外层有Viewgroup,那么此控件不能计算本身高度,导致没法看到期望的效果,下面我再次贴出完美解决此问题的代码
package com.app.widget; import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import com.app.R; public class AutoChangeLinesViewGroup extends ViewGroup { // 横向间距 private static int VIEW_WIDTH_MARGIN = 10; // 纵向间距 private static int VIEW_HEIGHT_MARGIN = 10; public AutoChangeLinesViewGroup(Context context) { super(context); // TODO Auto-generated constructor stub init(context); } public AutoChangeLinesViewGroup(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub init(context); } public AutoChangeLinesViewGroup(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub init(context); } private void init(Context context){ VIEW_WIDTH_MARGIN = (int) context.getResources().getDimension(R.dimen.nearby_releasse_thtem_tag_height); VIEW_HEIGHT_MARGIN = (int) context.getResources().getDimension(R.dimen.nearby_releasse_thtem_tag_width); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { // TODO Auto-generated method stub int width = 0; int height = 0; int row = 0 ; if(changed){ final int count = getChildCount(); for(int i = 0; i < count; i++){ final View child = this.getChildAt(i); int measuredWidth = child.getMeasuredWidth(); int measuredHeight = child.getMeasuredHeight(); width += measuredWidth + VIEW_WIDTH_MARGIN; height = row * ( measuredHeight + VIEW_HEIGHT_MARGIN ) + VIEW_HEIGHT_MARGIN + measuredHeight; if(width > getWidth()){ width = measuredWidth + VIEW_WIDTH_MARGIN; if(width > getWidth()){ width = getWidth() ; } row ++; height = row * ( measuredHeight + VIEW_HEIGHT_MARGIN ) + VIEW_HEIGHT_MARGIN + measuredHeight; // 超出最大范围之后不绘制 child.layout(0, height - measuredHeight, width - VIEW_WIDTH_MARGIN, height); }else { child.layout(width - measuredWidth - VIEW_WIDTH_MARGIN, height - measuredHeight, width - VIEW_WIDTH_MARGIN, height); } } } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 获取系统自动测量的该ViewGroup的大小 int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if(heightSize > 0 && widthSize > 0){ setMeasuredDimension(widthSize, heightSize); return ; } // 我们也可调用setMeasuredDimension()重新设置测量结果 // 修改了系统自动测量的子View的大小 int childCount = this.getChildCount(); int width = 0; int height = 0; int row = 0 ; for (int i = 0; i < childCount; i++) { View childView = getChildAt(i); int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); childView.measure(w, h); // 获取每个子View测量所得的宽和高 int childMeasuredWidth = childView.getMeasuredWidth(); int childMeasuredHeight = childView.getMeasuredHeight(); width += childMeasuredWidth + VIEW_WIDTH_MARGIN; height = row * ( childMeasuredHeight + VIEW_HEIGHT_MARGIN ) + VIEW_HEIGHT_MARGIN + childMeasuredHeight; if(width > widthSize){ width = childMeasuredWidth + VIEW_WIDTH_MARGIN; if(width > widthSize){ width = widthSize ; } row ++; height = row * ( childMeasuredHeight + VIEW_HEIGHT_MARGIN ) + VIEW_HEIGHT_MARGIN + childMeasuredHeight; } } setMeasuredDimension(widthSize, height); } }
需要的朋友自己下载