自定义流式布局FlowLayout
来源:互联网 发布:js日期插件只选择年月 编辑:程序博客网 时间:2024/04/29 10:10
应用截图
实现思路:
1.继承自ViewGroup
2.重写onMeasure()方法,根据测量模式测量出控件的宽度和高度(其中包含了子控件的margin值),通过setMeasuredDimension(newWidthSize, newHeightSize);设置控件的宽高
3.实现onLayout()方法,对它的每一个子View进行布局设置,规则为从左到右依次排列,该行放不下子控件则将子控件放到新的一行
一.自定义控件代码
public class FlowLayout extends ViewGroup { //存储该控件内的所有的子控件 private List<List<View>> viewList = new ArrayList<>(); //存储每一行中最大的高度作为该行的高度 private List<Integer> mLineHeights = new ArrayList<>(); public FlowLayout(Context context) { this(context, null); } public FlowLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FlowLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { return new MarginLayoutParams(getContext(), attrs); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //获取测量模式和大小 int widthSpec = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpec = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int newWidthSize = 0; int newHeightSize = 0; int currentWidth=0; int currentHeight=0; //根据不同模式设置大小 if (widthSpec == MeasureSpec.EXACTLY && heightSpec == MeasureSpec.EXACTLY) { newWidthSize = widthSize; newHeightSize = heightSize; } else { //通过计算出每个孩子的宽高相加后得到控件的宽高 int childNum = getChildCount(); List<View> lineViewList = new ArrayList<>(); for (int i = 0; i < childNum; i++) { //获得子控件 View childView = getChildAt(i); //对子控件进行测量 measureChild(childView, widthMeasureSpec, heightMeasureSpec); MarginLayoutParams params = (MarginLayoutParams) childView.getLayoutParams(); //子控件的宽度=自身宽度+左边距+右边距 高度=自身高度+上边距+下边距 int childWidth = childView.getMeasuredWidth() + params.leftMargin + params.rightMargin; int childHeight = childView.getMeasuredHeight() + params.topMargin + params.bottomMargin; //判断子控件所处位置是否超出父控件宽度 if (currentWidth + childWidth < widthSize) { //当前行中最大的宽度 currentWidth += childWidth; //获得当前行中最大的高度 currentHeight=Math.max(currentHeight, childHeight); //添加同一行子控件 lineViewList.add(childView); } else { //存储上一行的高度 mLineHeights.add(currentHeight); //所有行中最大的宽度 newWidthSize=Math.max(currentWidth,newWidthSize); //计算总共的高度 newHeightSize+=currentHeight+childHeight; //计算新一行的宽度 currentWidth=childWidth; currentHeight=childHeight; //存储上一行的所有子控件 viewList.add(lineViewList); //重新创建存储新行子控件的集合 lineViewList = new ArrayList<>(); lineViewList.add(childView); } if(i==childNum-1){//最后一行或者只有一行 //存储一行的高度 mLineHeights.add(currentHeight); //所有行中最大的宽度 newWidthSize = Math.max(newWidthSize,currentWidth); //计算总共的高度 newHeightSize+=currentHeight; //存储上一行的所有子控件 viewList.add(lineViewList); } } } setMeasuredDimension(newWidthSize, newHeightSize); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int left,top,right,bottom; int curTop = 0;//表示子控件的top值 int curLeft = 0;//表示子控件的left值 //遍历获取子控件并对其进行布局 for(int i = 0 ; i < viewList.size() ; i++) { //获取第i行中的所有子控件 List<View> viewList = this.viewList.get(i); for(int j = 0; j < viewList.size(); j++){ //获取第i行中第j个子控件 View childView = viewList.get(j); //获取控件的布局属性 MarginLayoutParams layoutParams = (MarginLayoutParams) childView.getLayoutParams(); //计算子控件的left,right,top,bottom值 left = curLeft + layoutParams.leftMargin; top = curTop + layoutParams.topMargin; right = left + childView.getMeasuredWidth(); bottom = top + childView.getMeasuredHeight(); //对子控件进行布局操作 childView.layout(left,top,right,bottom); //同一行中下一个子控件的left值为=当前控件left值+当前控件的宽度+左边距+右边距 curLeft += childView.getMeasuredWidth() + layoutParams.leftMargin + layoutParams.rightMargin; //设置点击事件 childView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(getContext(),"你好啊",Toast.LENGTH_SHORT).show(); } }); } //下一行的left初始化为0 curLeft = 0; //下一行的top值为上一行的高度值 curTop += mLineHeights.get(i); } //将集合清空 viewList.clear(); mLineHeights.clear(); }}
二.布局使用情况
<com.example.qdq.uidemo.FlowLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:text="中华人民共和国四川省成都市不存在服务区" android:textSize="18sp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:textSize="18sp" android:text="技术详情请拨打电话10086"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:text="fffffffff"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:text="呵呵呵俄呵呵呵俄呵呵呵"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:text="fffff"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:text="fffff"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:text="fffff"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:text="fffff"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:text="fffff"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:text="fffff"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:text="fffff"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:text="fffff"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:text="fffff"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/item_backgroud_shape" android:layout_margin="5dp" android:text="fffff"/> </com.example.qdq.uidemo.FlowLayout>
阅读全文
0 0
- 自定义流式布局FlowLayout
- 自定义流式布局FlowLayout
- 自定义ViewGroup实现流式布局FlowLayout
- Android自定义流式布局-FlowLayout
- 自定义流式布局控件FlowLayout
- 自定义ViewGroup,流式布局FlowLayout
- Android自定义流式布局-FlowLayout
- 自定义控件之-流式布局FlowLayout
- Android自定义控件--流式布局(FlowLayout)
- android_studio自定义FlowLayout流式布局
- FlowLayout实现自定义的流式布局
- FlowLayout流式布局
- FlowLayout流式布局
- 流式布局FlowLayout
- 流式布局FlowLayout
- 流式布局 FlowLayout
- FlowLayout,流式布局
- Android自定义控件--流式布局(FlowLayout)--自动适配
- 中国计算机学会CCF推荐国际学术会议和期刊目录-人机交互与普适计算
- C++ sizeof()详解
- bzoj 3509 [CodeChef] COUNTARI
- 查看Android ADT Plugin版本号的方法
- 第二章 为博客添加高级功能
- 自定义流式布局FlowLayout
- 一般名片的尺寸是多少
- adb命令之pm hide 与 disable
- scrapy-redis环境配置
- gcc 编译信息输出到文本文件
- matlab基本数组和向量操作
- 第三章 扩展你的博客应用
- 关于springMVC文件上传过程中一个有意思的小细节
- 浅析Handler引起的内存泄漏及解决方法