Android 自定义流式布局

Android 自定义流式布局自定义流式布局自定义流式布局 处理 margin 值 支持 addView 和 XML 布局 代码实现 publicclassT privatefinal ChildInfo childrenInfo newArrayList lt gt publicTagLay Contextconte super context pub ChildInfo

自定义流式布局

自定义流式布局,处理margin值,支持addView和XML布局。

在这里插入图片描述

代码实现

public class TagLayout extends ViewGroup { 
    private int horizontalSpace = dp2px(20); private int verticalSpace = dp2px(16); //所有子View private ArrayList<ArrayList<View>> allViewList = new ArrayList<>(); //存储每一行高度 private ArrayList<Integer> lineHeightList = new ArrayList<>(); public TagLayout(Context context) { 
    super(context); } public TagLayout(Context context, AttributeSet attrs) { 
    super(context, attrs); } public TagLayout(Context context, AttributeSet attrs, int defStyleAttr) { 
    super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    allViewList.clear(); lineHeightList.clear(); //获取父View的模式和尺寸 int widthSize = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); //定义TagLayout已使用宽和高空间 int widthUsed = 0; int heightUsed = 0; //定义单行的宽的已使用空间 int lineWidthUsed = 0; //定义单行最大值 int lineMaxHeight = 0; //一行的子View ArrayList<View> lineViews = new ArrayList<>(); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { 
    View childView = getChildAt(i); measureChildWithMargins(childView, widthMeasureSpec, 0, heightMeasureSpec, heightUsed); //换行 if (widthMode != MeasureSpec.UNSPECIFIED && getPaddingLeft() + getPaddingRight() + lineWidthUsed + childView.getMeasuredWidth() + horizontalSpace > widthSize) { 
    allViewList.add(lineViews); lineHeightList.add(lineMaxHeight); lineViews = new ArrayList<>(); widthUsed = Math.max(widthUsed, lineWidthUsed); heightUsed += lineMaxHeight + verticalSpace; lineWidthUsed = 0; lineMaxHeight = 0; measureChildWithMargins(childView, widthMeasureSpec, 0, heightMeasureSpec, heightUsed); } lineViews.add(childView); lineWidthUsed += childView.getMeasuredWidth() + horizontalSpace; lineMaxHeight = Math.max(lineMaxHeight, childView.getMeasuredHeight()); //处理最后一行 if (i == childCount - 1) { 
    allViewList.add(lineViews); lineHeightList.add(lineMaxHeight); widthUsed = Math.max(widthUsed, lineWidthUsed); heightUsed += lineMaxHeight; } } int selfWidth = widthUsed + getPaddingLeft() + getPaddingRight(); int selfHeight = heightUsed + getPaddingTop() + getPaddingBottom(); setMeasuredDimension(selfWidth, selfHeight); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { 
    int lineCount = allViewList.size(); int left = getPaddingLeft(); int top = getPaddingTop(); for (int i = 0; i < lineCount; i++) { 
    ArrayList<View> lineViewList = allViewList.get(i); for (View childView : lineViewList) { 
    int childLeft = left; int childTop = top; int childRight = childLeft + childView.getMeasuredWidth(); int childBottom = childTop + childView.getMeasuredHeight(); childView.layout(childLeft, childTop, childRight, childBottom); left = childRight + horizontalSpace; } int lineHeight = lineHeightList.get(i); top += lineHeight + verticalSpace; left = getPaddingLeft(); } } @Override protected LayoutParams generateDefaultLayoutParams() { 
    return new MarginLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); } @Override public LayoutParams generateLayoutParams(AttributeSet attrs) { 
    return new MarginLayoutParams(getContext(), attrs); } @Override protected LayoutParams generateLayoutParams(LayoutParams p) { 
    return new MarginLayoutParams(p); } @Override protected boolean checkLayoutParams(LayoutParams p) { 
    return p instanceof MarginLayoutParams; } public int dp2px(float dpValue) { 
    float scale = Resources.getSystem().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } } 

代码下载

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/233353.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 简述android触屏事件的处理_移动端touch事件有哪些

    简述android触屏事件的处理_移动端touch事件有哪些本文介绍了Android系统中触屏事件的相关知识,包括触屏事件的产生,分类,触屏事件序列,以及触屏事件在代码中的表示方式。了解这些内容,是理解Android触屏事件的分发,拦截和处理的基础。

    2025年10月19日
    3
  • fastjson注解有哪些(json的注释)

    阿里的fastJoson是一个非常好用的类,json转化的时候用到的jsonField特此记录一下fastjson之@JSONField注解的几个的使用详细示范好文2https://blog.csdn.net/u011425751/article/details/51219242…

    2022年4月10日
    129
  • base编码器_base100编码

    base编码器_base100编码Base64编码是一种基于64个可打印字符来表示二进制数据的方法。目前Base64已经成为网络上常见的传输8位二进制字节代码的编码方式之一。为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字节,例如:传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通过邮件传送。这样用途就受到了很大的限制。图片的二进制流的每个字节不可能全部是可…

    2022年10月9日
    2
  • java单例指令重排_java实现数组去重

    java单例指令重排_java实现数组去重java指令重排案例。

    2022年10月17日
    2
  • Java安全之反序列化回显研究

    Java安全之反序列化回显研究0x00前言续上文反序列化回显与内存马,继续来看看反序列化回显的方式。上篇文中其实是利用中间件中存储的Request和Response对象来进行回显。但并不止这么

    2021年12月13日
    67
  • C语言中从键盘输入字符串时的一些问题[通俗易懂]

    C语言中从键盘输入字符串时的一些问题[通俗易懂]C语言中从键盘输入字符串时的一些问题1.scanf()scanf()在输入字符串时有很大的弊端,例如:1).scanf()在从键盘读入字符时并不会根据所定义的字符数组的大小来控制读入多少个,而是从scanf()中传入的地址开始一直访问下一个元素的内存,碰见空格符或者回车符时才停止读入并存入结束符’\0’,这就有可能造成了一个在C中非常严重的问题,访问非法内存.如果…

    2025年6月1日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号