固定容器的宽高信息,往容器内添加子view,子view按行排列,当宽度快超出容器宽度时,换行继续排列
import android.content.Context; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; public class FlowContainer extends ViewGroup{ private final static int VIEW_MARGIN = 2;//子view自己的间距 private int clientWidth; public FlowContainer(Context context) { super(context); } public FlowContainer(Context context, AttributeSet attrs) { super(context, attrs); } public FlowContainer(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ //获取整个flowContainer的宽度 clientWidth = MeasureSpec.getSize(widthMeasureSpec); //从第一行开始测量 int row = 0; int lengthX = 0; int lengthY = 0; //循环测量子view,得到子view最终占flowContainer宽高 for(int index = 0; index < getChildCount(); index++){ View child = getChildAt(index); if(child.getVisibility() == View.GONE){ continue; } //子view的宽高不限制,获取子view自己给定的宽高信息 child.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED); int width = child.getMeasuredWidth(); int height = child.getMeasuredHeight(); lengthX += width + VIEW_MARGIN; lengthY = row * (height + VIEW_MARGIN) + VIEW_MARGIN + height; //第一行 所有子view的宽度>父容器宽度 准备换行 if((lengthX + VIEW_MARGIN) > clientWidth){ //下一行的 宽度开始计算 lengthX = width + VIEW_MARGIN; row++; //下一行后 总宽度 lengthY = row * (height +VIEW_MARGIN) + VIEW_MARGIN + height; } } lengthY = lengthY + VIEW_MARGIN; //设置容器所需的宽度和高度(宽度为父宽,高为所有子view算出来的) setMeasuredDimension(clientWidth, lengthY); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { int row = 0; top = VIEW_MARGIN; int lengthX = left; int lengthY = 0; for(int i = 0; i < getChildCount(); i++){ View child = this.getChildAt(i); if(child.getVisibility() == View.GONE){ continue; } int width = child.getMeasuredWidth(); int height = child.getMeasuredHeight(); lengthX += width + VIEW_MARGIN; lengthY = row * (height + VIEW_MARGIN) + VIEW_MARGIN + height + top; if((lengthX + VIEW_MARGIN) > right){ lengthX = width + VIEW_MARGIN + left; row++; lengthY = row * (height + VIEW_MARGIN) +VIEW_MARGIN + height + top; } child.layout(lengthX - width, lengthY - height, lengthX, lengthY); } } }
布局文件如下:这里的容器高度随子view的多少撑高,但是高度超出屏幕后无法滑动,所以外部套一个scrollView来滑动
<?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <com.whc.view.FlowContainer android:id="@+id/flow_container" android:layout_width="match_parent" android:layout_height="wrap_content"> </com.whc.view.FlowContainer> </ScrollView>
activity中就随便放置多个textView来展示效果吧
import java.util.ArrayList; import java.util.List; import com.whc.view.FlowContainer; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class FlowActivity extends Activity { private FlowContainer flowContainer; private List<String> list; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.flow_activity); flowContainer = (FlowContainer) findViewById(R.id.flow_container); initData(); initView(); } private void initView() { for(int i = 0; i<list.size(); i++){ TextView tv = new TextView(this); tv.setText(list.get(i)); flowContainer.addView(tv); } } private void initData() { list = new ArrayList<String>(); for(int i = 0; i < 500; i++){ list.add("第"+i+"几个view"); } } }
这样容器内的子textView就会横向排列,当快超出容器宽度时,换行继续
时间: 2024-10-02 23:16:05