之前项目遇到需要自动换行的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);
}
}
需要的朋友自己下载