自定义ViewGroup实现控件自动换行

2023-11-14

首先看效果如下
自定义ViewGroup
首先我们需要自定义ViewGroup 重写onMeasure和onLayout将布局摆放好然后在通过适配器添加子view
代码如下

public class MyViewGroup extends ViewGroup {
    List<List<View>> childList;

    public MyViewGroup(Context context) {
        this(context, null);
    }

    public MyViewGroup(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyViewGroup(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) {
        childList = new ArrayList<>();
        int viewWidth = MeasureSpec.getSize(widthMeasureSpec);
        int viewHeight = 0;
        int lineWidth = getPaddingLeft();
        int count = getChildCount();
        List<View> viewList = new ArrayList<>();
        childList.add(viewList);
        for (int i = 0; i < count; 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 (lineWidth + childWidth > viewWidth) {//换行
                viewHeight += childHeight;
                lineWidth = childWidth + getPaddingLeft();
                viewList = new ArrayList<>();
                childList.add(viewList);
                viewList.add(childView);
            } else {
                lineWidth += childWidth;
                viewList.add(childView);
            }
        }
        setMeasuredDimension(viewWidth, viewHeight);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int left, top = 0, right = 0, bottom = 0;
        for (List<View> viewList : childList) {
            left = getPaddingLeft();
            for (View view : viewList) {
                MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
                left += params.leftMargin;
                right = left + view.getMeasuredWidth() + params.rightMargin;
                int viewTop = top + params.topMargin;
                bottom = top + view.getMeasuredHeight() + params.bottomMargin;
                view.layout(left, viewTop, right, bottom);
                left += view.getMeasuredWidth() + params.rightMargin;
            }
            View child = viewList.get(0);
            MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams();
            top += child.getMeasuredHeight() + params.topMargin + params.bottomMargin;
        }
    }

    public void setAdapter(MyViewGroupAdapter adapter) {
        removeAllViews();
        List<String> mDates = adapter.getDates();
        LayoutInflater inflater = LayoutInflater.from(getContext());
        for (String mDate : mDates) {
            View view = inflater.inflate(R.layout.item_vg, this, false);
            ((TextView) view.findViewById(R.id.tv_content)).setText(mDate);
            addView(view);
        }
        postInvalidate();
    }

    public interface MyViewGroupAdapter {
        public List<String> getDates();
    }
}

这里需要注意的使我们需要重写generateLayoutParams这个方法返回MarginLayoutParams这样我们才能通过这个类获取我们设置的margin值

最后我们需要在activity中调
代码如下

MyViewGroup vg = (MyViewGroup) findViewById(R.id.vg);
        vg.setAdapter(new MyViewGroup.MyViewGroupAdapter() {
            @Override
            public List<String> getDates() {
                List<String> dates = new ArrayList<>();
                for (int i = 0; i < 20; i++) {
                    if (i == 9) {
                        dates.add("sssssssssskkkkkss22222ssssssssssssssssssssss");
                    }
                    dates.add("---test---->" + i);
                }
                return dates;
            }
        });

item_vg的代码如下

<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tv_content"
    android:layout_width="wrap_content"
    android:background="@drawable/rountbg"
    android:padding="5dp"
    android:layout_margin="5dp"
    android:layout_height="wrap_content"
    android:orientation="vertical"/>

activity中调用代码如下


        <com.mvvm.MyViewGroup
            android:id="@+id/vg"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#00ffff"/>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义ViewGroup实现控件自动换行 的相关文章

  • 使用 WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH 获取所有 MotionEvent

    我的问题直接涉及到这个question https stackoverflow com q 4481226 394933 这个问题的答案表明了如何创建一个ViewGroup 将其嵌入到WindowManager 并允许WindowManag
  • 无法滚动所有 ListView 项目

    我无法滚动所有列表项 我可以在模拟器上用鼠标滚动条滚动它 但如果想在触摸时滚动它 它就不会滚动 有人可以帮我吗
  • Laravel 5 获取视图名称

    我正在努力获取 L5 中的视图名称 就像在 WP 中一样 我想添加特定的页面名称 视图名称 用于样式 如下所示 div class page login h1 Inloggen h1 div div class page register
  • laravel 5 根据路由返回 HTML 或 JSON

    我想显示不同的输出 JSON 或 HTML 我无法使用 Request ajax 功能 因为我只是收到正常请求 JSON 响应不是基于 XHR 请求 是否有可能区分不同路线的输出 例如 检查控制器是否由前缀为 mob 的路由调用 然后根据该
  • Android:更改WindowManager添加的View的LayoutParams

    我有叠加层View管理者WindowManager 就像在这个问题 http goo gl OD1ij 简而言之 它看起来像这样 WindowManager wm WindowManager getSystemService WINDOW
  • 只有创建视图层次结构的原始线程才能触摸其视图错误

    一切正常 除非到达代码的最后部分 注册成功 然后标题中提到的错误出现在registerDialog消息部分中 我做错了什么吗 谁能帮我检查我的代码 非常感谢 该应用程序没有崩溃 尽管它只是退出回到应用程序主页 如果我再次按下注册按钮 它将返
  • 有没有办法在android 2.1中不使用动画来旋转按钮

    我正在寻找旋转按钮的方法 不使用动画 我不想使用动画 因为this https stackoverflow com questions 8037185 onlclick listener is not working properly 如果
  • CouchDB“加入”两个文档

    我有两个看起来有点像这样的文档 Doc id AAA creator id data DataKey id credits left 500 times used 0 data id AAA 我想要做的是创建一个视图 它允许我传递 Data
  • 如何确定视图的列是派生的还是常量?

    假设我有下表 create table t Item ItemID int not null identity 1 1 constraint PK Item primary key Description varchar 256 not n
  • 使用自定义视图填充 ListFragments?

    以前 我可以将布局扩展为 ListView 的自定义视图层次结构 但我不知道如何对 listFragment 执行相同的操作 假设我有一个 item list 布局 其中有一个 ImageView 和 2 个文本视图 我想将其膨胀以在我的
  • MVC 在视图之间传输数据

    我刚刚开始学习 MVC 并试图了解它是如何工作的 我不想将用户发送到所有编辑 插入和列表操作的不同视图 在我的示例应用程序中 视图包含项目列表 列表下方有一个带有操作 Controller Create 的表单 用于插入新项目 但没有创建视
  • 在 Kohana 3.2 视图中输出图像

    我有以下脚本将图像输出到浏览器 效果很好 file to output SERVER DOCUMENT ROOT static imgs uploads 20110318172207 16 jpg header Content Type i
  • 在 Zend Framework 应用程序中,/views/filters 有什么用途?

    我知道视图助手的作用 view helpers 但我不知道视图过滤器 view filters 是什么 或者它的用途是什么 有人可以解释一下这个问题吗 谢谢你 在渲染视图结束时 Zend View 将输出传递给您已注册的任何过滤器 方法是调
  • 在视图上按下按键时不会调用 onKeyDown

    我有一个包含两个视图的活动 一个视图重写 onDraw 并正确处理 onTouchEvent 但是当我尝试检索第二个视图的 onKeyDown 时 它没有给我任何结果 相反 当我按下后退按钮或任何其他键盘按钮时 会调用 onKeyDown
  • 扩展 EditText 以赋予其额外的“默认”功能的正确方法是什么

    我想知道是否可以向 EditText 添加功能 以便当我在布局 xml 中包含新扩展的字段时 我不必向 Activity 类添加任何代码以使其以特定方式运行 例如 我想创建一个 EditPhone 字段 它只是一个 EditText 它具有
  • Pandas:了解操作何时影响原始数据帧

    我喜欢 pandas 并且已经使用它很多年了 并且非常有信心我能够很好地掌握如何对数据帧进行子集化并适当地处理视图与副本 尽管我使用了很多断言来确保 我还知道有很多关于SettingWithCopyWarning的问题 例如如何处理Pand
  • 将数据传递给视图时,node ejs 引用错误数据未在 eval 处定义

    我已经接近使用express和ejs的节点应用程序 但是当我尝试将数据从控制器传递到我的视图时 如下所示 var myData theData data res render path join dirname views index my
  • CodeIgniter:将参数从视图传递到控制器?

    编辑 现在使用下面的代码 我不确定如何正确打印书签和标签 我对 CI 完全陌生 最近遇到了障碍 我非常不确定如何将函数参数从视图文件传递到控制器 以便我可以在函数上使用它 我在视图上有一个 foreach 循环 遍历函数 get lates
  • 我可以为 Android Activity 分配“默认”OnClickListener() 吗?

    我有一个 Activity 对于布局中的每个小部件 我调用 setOnClickListener 来分配我的 OnClick 处理程序 在我的 OnClick 处理程序中 我使用 switch 语句根据 View 参数的 ID 为每个按钮执
  • Android View Canvas onDraw 未执行

    我目前正在开发一个自定义视图 它在画布上绘制一些图块 这些图块是从多个文件加载的 并将在需要时加载 它们将由 AsyncTask 加载 如果它们已经加载 它们只会被绘制在画布上 这工作正常 如果加载了这些图片 AsyncTask 就会触发v

随机推荐

  • centos 安装alien

    出处 http linux4you in install netapp oncommand system manger on centos 1 在root权限下执行命令 sudo su 2 安装alien需要的依赖包 yum y insta
  • springmvc源码学习(二十七)异步任务超时异常的执行流程

    目录 前言 一 示例 二 源码分析 总结 前言 本文分析异步任务出现超时及异常的情况时的处理流程 一 示例 设置超时时间为2s 但任务需要执行10s ApiOperation value test notes test GetMapping
  • zsh + oh-my-zsh 主题预览

    The Themes robbyrussell the default that Robby uses The rest of the themes in alphabetical order af magic afowler agnost
  • 区块链技术之哈希指针

    hello 大家好 我们第三期的区块链技术分享来啦 那么话不多说 我们开始吧 提起区块链 大家可能都会提到 不可篡改 但是为什么区块链不可篡改呢 先给出答案 这与区块链的数据结构哈希指针和默克尔树有关 那么我们今天先分享哈希指针相关的内容
  • cron linux_如何在Linux中使用cron

    cron linux 本文最初发布于2017年11月 现已更新以包含其他信息 成为系统管理员的挑战 其中有很多优点 之一是当您想睡觉时正在运行任务 例如 某些任务 包括定期重复执行的任务 需要在没有人使用计算机资源的情况下通宵运行或在周末运
  • 211和985区别:

    985工程 是在 211工程 的基础上 根据我国国防 民用 东 中 西部协调发展的原则而筛选出来的
  • 获取网页的html文本(用selenium+chrome headless进行js异步加载内容),返回BeautifulSoup的soup对象

    import requests from bs4 import BeautifulSoup from selenium import webdriver def gethtml url js False if js False return
  • 1.代码片断收集-数据拷贝效率问题

    上面是我创建的群聊 欢迎新朋友的加入 1 基本信息 mycode 收录一些简单的代码片段 Gitee com 克隆链接 mycode 收录一些简单的代码片段 目的 记录和收集一些常用的代码片段 同时也欢迎网友提交push申请 共同完善 开发
  • 05C++11多线程编程之使用正确的共享代码案例引入互斥量mutex的概念、用法

    05C 11多线程编程之使用正确的共享代码案例引入互斥量mutex的概念 用法 1 共享代码案例概念分析 1 网络游戏服务器 两个自己创建的线程 一个线程收集玩家命令 一个数字代表玩家发来的命令 并把命令写到一个队列中 另外一个线程从队列中
  • 基于pytorch的无需分割字符的车牌识别

    传统车牌识别 传统的车牌识别需要先检测出车牌 检测出车牌后通过 像素映射 或者 联通区查找 的方法分割出单个的文字 然后单独识别每个文字 传统的车牌识别不仅繁琐 而且切割文字的效果也很难令人满意 因此 能不能绕开字符分割的问题 直接识别车牌
  • 系分 - 系统安全分析与设计

    个人总结 仅供参考 欢迎加好友一起讨论 文章目录 系分 系统安全分析与设计 考点摘要 对称加密 非对称加密 信息摘要 数字签名 数字证书 数字信封 PKI公钥体系 网络安全 安全协议 网络安全 网络威胁与攻击 防火墙 功能 防火墙 分类 防
  • Matlab遗传算法工具箱及应用

    目录 第一章 遗传算法概述 1 1遗传算法概念 1 2遗传算法与爬山法的比较 1 3遗传算法的基本原理与方法 第二章 遗传算法应用举例 2 1简单一元函数优化实例 参考资料 Matlab遗传算法工具箱及应用 主编 雷英杰 张善文 西安电子科
  • SpringBoot——加载测试专用的配置类

    加载测试专用的配置类 之前我们介绍了如何在测试类中加载专用的测试属性 这次我们来看如何在测试类中加载专用的测试类 创建配置类 首先创建一个配置类 并且创建一个第三方的Bean模拟这是一个要在测试用例中引用的第三方Bean 创建测试用例 创建
  • LTE小区搜索过程及SCH/BCH设计

    终端开机过程 在小区搜索之前 需要完成PLMN的选定 再去搜索小区相关信息 PLMN 公共陆地移动网络 是一个标识 由MCC和MNC组成 比如中国电信46011 460是MCC 11是MNC 两个标识都是2 3位 那终端是如何搜索PLMN的
  • WIN7环境下cmd javac不是内部或外部命令

    一般步骤如下 网上摘抄部分 JAVA HOME指明JAVA安装路径 值设为 C Program Files Java jre7 刚才安装时所选择的路径 每个人可能不一样 此路径下包括lib bin jre等文件夹 Path值设为 JAVA
  • GNU __attribute__ 机制

    http blog 163 com sunm lin blog static 9192142200741533038695
  • 在服务器跑vue不能访问?是你的host设置问题

    看了csdn的一堆文章 大都是部署的 也就是 经过了 npm run build 之后 打包好的压缩工程部署 比如 https blog csdn net weixin 43690623 article details 122718677
  • Ubuntu开机后卡死只有左上角有一个下划线不停闪烁

    千万不要乱设置东西 先按一下Ctrl Alt F2打开tty模式检查问题出在哪了 之后会让你输入用户名和密码 就平时开机正常登录那样 然后相当于进入了一个平时用的终端 只是这个终端占据了整个屏幕 平时用的指令都可以用 接着你去检查到底出了什
  • myisamchk命令使用总结

    author sakte time 2012 02 28 myisamchk命令使用总结 myisamchk实用程序可以用来获得有关你的数据库表的统计信息或检查 修复 优化他们 1 常用于myisamchk的检查选项 information
  • 自定义ViewGroup实现控件自动换行

    首先看效果如下 首先我们需要自定义ViewGroup 重写onMeasure和onLayout将布局摆放好然后在通过适配器添加子view 代码如下 public class MyViewGroup extends ViewGroup Lis