当前位置: 首页 > news >正文

Android可换行的RadioGroup

        Android可换行的RadioGroup,有时候需要换行显示的单选列表,当然可以有多种实现方式,比如recycleview或者listview实现,本文采用的是RadioGroup+rediobutton方式实现。

一、首先自定义view


public class WrapRadioGroup extends RadioGroup {private static final String TAG = "RadioGroupEx";public WrapRadioGroup(Context context) {super(context);}public WrapRadioGroup(Context context, AttributeSet attrs) {super(context, attrs);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int widthSize = MeasureSpec.getSize(widthMeasureSpec);int widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);//调用ViewGroup的方法,测量子viewmeasureChildren(widthMeasureSpec, heightMeasureSpec);//最大的宽int maxWidth = 0;//累计的高int totalHeight = 0;//当前这一行的累计行宽int lineWidth = 0;//当前这行的最大行高int maxLineHeight = 0;//用于记录换行前的行宽和行高int oldHeight;int oldWidth;int count = getChildCount();//假设 widthMode和heightMode都是AT_MOSTfor (int i = 0; i < count; i++) {View child = getChildAt(i);MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams();//得到这一行的最高oldHeight = maxLineHeight;//当前最大宽度oldWidth = maxWidth;int deltaX = child.getMeasuredWidth() + params.leftMargin + params.rightMargin;if (lineWidth + deltaX + getPaddingLeft() + getPaddingRight() > widthSize) {//如果折行,height增加//和目前最大的宽度比较,得到最宽。不能加上当前的child的宽,所以用的是oldWidthmaxWidth = Math.max(lineWidth, oldWidth);//重置宽度lineWidth = deltaX;//累加高度totalHeight += oldHeight;//重置行高,当前这个View,属于下一行,因此当前最大行高为这个child的高度加上marginmaxLineHeight = child.getMeasuredHeight() + params.topMargin + params.bottomMargin;
//                Log.v(TAG, "maxHeight:" + totalHeight + "---" + "maxWidth:" + maxWidth);} else {//不换行,累加宽度lineWidth += deltaX;//不换行,计算行最高int deltaY = child.getMeasuredHeight() + params.topMargin + params.bottomMargin;maxLineHeight = Math.max(maxLineHeight, deltaY);}if (i == count - 1) {//前面没有加上下一行的搞,如果是最后一行,还要再叠加上最后一行的最高的值totalHeight += maxLineHeight;//计算最后一行和前面的最宽的一行比较maxWidth = Math.max(lineWidth, oldWidth);}}//加上当前容器的padding值maxWidth += getPaddingLeft() + getPaddingRight();totalHeight += getPaddingTop() + getPaddingBottom();setMeasuredDimension(widthMode == MeasureSpec.EXACTLY ? widthSize : maxWidth,heightMode == MeasureSpec.EXACTLY ? heightSize : totalHeight);}@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {int count = getChildCount();//pre为前面所有的child的相加后的位置int preLeft = getPaddingLeft();int preTop = getPaddingTop();//记录每一行的最高值int maxHeight = 0;for (int i = 0; i < count; i++) {View child = getChildAt(i);MarginLayoutParams params = (MarginLayoutParams) child.getLayoutParams();//r-l为当前容器的宽度。如果子view的累积宽度大于容器宽度,就换行。if (preLeft + params.leftMargin + child.getMeasuredWidth() + params.rightMargin + getPaddingRight() > (r - l)) {//重置preLeft = getPaddingLeft();//要选择child的height最大的作为设置preTop = preTop + maxHeight;maxHeight = getChildAt(i).getMeasuredHeight() + params.topMargin + params.bottomMargin;} else { //不换行,计算最大高度maxHeight = Math.max(maxHeight, child.getMeasuredHeight() + params.topMargin + params.bottomMargin);}//left坐标int left = preLeft + params.leftMargin;//top坐标int top = preTop + params.topMargin;int right = left + child.getMeasuredWidth();int bottom = top + child.getMeasuredHeight();//为子view布局child.layout(left, top, right, bottom);//计算布局结束后,preLeft的值preLeft += params.leftMargin + child.getMeasuredWidth() + params.rightMargin;}}}

二、布局直接引用

<LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><csu.xiaoya.robotApp.ui.view.WrapRadioGroupandroid:id="@+id/rg_bls"android:layout_width="438dp"android:layout_height="179dp"android:layout_below="@id/monitor_remd"android:layout_alignParentRight="true"android:layout_marginTop="@dimen/dp_15"android:layout_marginRight="@dimen/dp_24"android:orientation="horizontal"android:padding="1dp"app:maxWidth="300dp"><RadioButtonandroid:id="@+id/rb_date_day"android:layout_width="@dimen/dp_84"android:layout_height="@dimen/dimen_48"android:background="@drawable/bls_am_2h_sg"android:button="@null"android:checked="true"android:layout_marginLeft="@dimen/dp_10"android:gravity="center"android:text="随机血糖"android:textColor="@color/white"android:textSize="@dimen/sp_10" /><RadioButtonandroid:id="@+id/rb_date_week"android:layout_width="@dimen/dp_84"android:layout_height="@dimen/dimen_48"android:layout_marginLeft="@dimen/dp_10"android:background="@drawable/bls_am_2h_sg"android:button="@null"android:gravity="center"android:text="空腹血糖"android:textColor="@color/white"android:textSize="@dimen/sp_10" /><RadioButtonandroid:layout_width="@dimen/dp_84"android:layout_height="@dimen/dimen_48"android:layout_marginLeft="@dimen/dp_10"android:background="@drawable/bls_am_2h_sg"android:button="@null"android:gravity="center"android:text="早餐后2小时"android:textColor="@color/white"android:textSize="@dimen/sp_10" /><RadioButtonandroid:layout_width="@dimen/dp_84"android:layout_height="@dimen/dimen_48"android:layout_marginLeft="@dimen/dp_10"android:background="@drawable/bls_am_2h_sg"android:button="@null"android:gravity="center"android:text="早餐后2小时"android:textColor="@color/white"android:textSize="@dimen/sp_10" /><RadioButtonandroid:layout_width="@dimen/dp_84"android:layout_height="@dimen/dimen_48"android:layout_marginLeft="@dimen/dp_10"android:layout_marginTop="@dimen/dp_10"android:background="@drawable/bls_am_2h_sg"android:button="@null"android:gravity="center"android:text="早餐后2小时"android:textColor="@color/white"android:textSize="@dimen/sp_10" /></csu.xiaoya.robotApp.ui.view.WrapRadioGroup></LinearLayout>

三、背景样式bls_am_2h_sg

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:width="84dp" android:height="48dp" android:state_checked="false"><shape android:shape="rectangle"><solid android:color="#ff27b074" /><corners android:bottomLeftRadius="5dp" android:bottomRightRadius="5dp" android:topLeftRadius="5dp" android:topRightRadius="5dp" /></shape></item><item android:width="88dp" android:height="50dp" android:state_checked="true"><shape android:shape="rectangle"><solid android:color="#ff27b074" /><corners android:bottomLeftRadius="5dp" android:bottomRightRadius="5dp" android:topLeftRadius="5dp" android:topRightRadius="5dp" /></shape></item>
</selector>

四、大功告成

相关文章:

Android可换行的RadioGroup

Android可换行的RadioGroup,有时候需要换行显示的单选列表&#xff0c;当然可以有多种实现方式&#xff0c;比如recycleview或者listview实现&#xff0c;本文采用的是RadioGrouprediobutton方式实现。 一、首先自定义view public class WrapRadioGroup extends RadioGroup {pr…...

【ASP.NET Core 基础知识】--环境设置

一、简介 1.1 .NET Core SDK 概述 .NET Core SDK&#xff08;Software Development Kit&#xff09;是Microsoft推出的一个开源跨平台框架&#xff0c;用于开发和部署.NET应用程序。它是.NET Core平台的核心组件之一&#xff0c;为开发者提供了在多个操作系统上构建高性能、可…...

docker/华为云cce 部署nacos 2.3.0 集群模式

镜像地址 https://hub.docker.com/r/nacos/nacos-server 版本 nacos/nacos-server:v2.3.0-slim 关键环境变量 使用mysql数据源 变量值备注MODEcluster启用集群模式MYSQL_SERVICE_DB_NAME数据库名MYSQL_SERVICE_USER数据库用户名MYSQL_SERVICE_PASSWORD数据库密码SPRING_D…...

Doris 数据模型—Aggregate 模型

Doris 数据模型—Aggregate 模型 文章目录 Doris 数据模型—Aggregate 模型基本概念Aggregate 模型示例1:导入数据聚合示例2:保留明细数据示例3:导入数据与已有数据聚合Aggregate 模型限制Aggregate 模型使用场景本文主要从逻辑层面,描述 Doris 的数据模型,以帮助用户更好…...

数据库管理-第130期 JSON二元性(20240109)

数据库管理130期 2024-01-09 第130期 JSON二元性&#xff08;20240109&#xff09;1 简介2 关系型表和JSON存储的优劣3 Oracle JSON关系型二元性视图总结 第130期 JSON二元性&#xff08;20240109&#xff09; 上周&#xff0c;又双叒飞了一趟上海&#xff0c;也是2024年第一飞…...

k8s--动态pvc和pv

前情回顾 存储卷&#xff1a; emptyDir 容器内部&#xff0c;随着pod销毁&#xff0c;emptyDir也会消失 不能做数据持久化 hostPath&#xff1a;持久化存储数据 可以和节点上目录做挂载。pod被销毁了数据还在 NFS&#xff1a;一台机器&#xff0c;提供pod内容器所有的挂载点…...

C++:常量

const的最初动机 const的使用方法 使用const的好处是允许指定一种语义上的约束&#xff0c;即某种对象不能被修改&#xff0c;且由编译器具体实施这种约束。 const声明格式&#xff1a;const 类型名 对象名;修饰普通变量&#xff0c;时期不能被随意修改 【注意】1.C中的const…...

java JDBC 连接数据库

必须先插入工具包 DataSource ds JdbcHelper.getDs();System.out.println(ds);JdbcTemplate jdbcTemplatenew JdbcTemplate(ds);System.out.println(jdbcTemplate);//新增String sql1"insert into biao values(null,?,?,?)";int ijdbcTemplate.update(sql1,"…...

图神经网络|5.消息传递的计算方法 6.多层GNN的作用

5.消息传递的计算方法 边的存放方式 注意&#xff0c;在实际的边的实现方式中&#xff0c;并不是以邻接矩阵来进行实现的&#xff0c;这是因为在图的更新中&#xff0c;用邻接矩阵进行更新所占用的时间开销相对大&#xff0c;二是因为领接矩阵占用的空间大&#xff08;N方&am…...

构建中国人自己的私人GPT

创作不易&#xff0c;请大家多鼓励支持。 在现实生活中&#xff0c;很多人的资料是不愿意公布在互联网上的&#xff0c;但是我们又要使用人工智能的能力帮我们处理文件、做决策、执行命令那怎么办呢&#xff1f;于是我们构建自己或公司的私人GPT变得非常重要。 先看效果 一、…...

添加气泡与菜单

目录 1、添加气泡 1.1、文本提示气泡 1.2、带按钮的提示气泡 1.3、自定义气泡 2、菜单 2.1、创建默认样式的菜单 2.2、创建自定义样式的菜单 1、添加气泡 Popup属性可绑定在组件上显示气泡弹窗提示&#xff0c;设置弹窗内容、交互逻辑和显示状态。主要用于…...

python代码练习:双指针法

题目一&#xff1a;移除元素 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不…...

C++系列十七:访问控制符

访问权限控制符 一、public访问权限二、private访问权限三、protected访问权限 在C中&#xff0c;访问权限控制符用于限制类成员的访问权限&#xff0c;主要包括public、private和protected三种。这些访问权限控制符用于控制类成员的访问级别&#xff0c;从而保证数据的封装性和…...

postgresql 最简主从配置

实验目的 配置一个最简的主从环境&#xff0c;了解基本的主从配置。 环境参数 操作系统CentOS Linux release 7.9.2009 (Core)数据库版本PostgreSQL 10.23主库端口15431备库端口15432 因为只是做实验&#xff0c;所以主备库放在同一台机器上&#xff0c;仅通过端口区分主备…...

ubuntu 安装 anaconda

ubuntu 安装 anaconda 下载 wget https://repo.anaconda.com/archive/Anaconda3-2023.09-0-Linux-x86_64.sh安装 bash Anaconda3-2023.09-0-Linux-x86_64.sh2.1 回车继续 2.2 许可协议 输入 q 退出阅读许可协议 2.3 输入 yes 接受 许可协议 2.4 设置 anaconda 安装位置 如不需…...

DOM 被劫持

文档对象模型&#xff08;DOM&#xff09;充当着 HTML 和 JavaScript 之间的接口&#xff0c;搭建起静态内容与动态交互之间的桥梁&#xff0c;对现代 Web 开发而言&#xff0c;DOM 的作用不可或缺。 然而&#xff0c;DOM 也有一个致命的陷阱 —— DOM 劫持。DOM 劫持是指当 H…...

PIG框架学习2——资源服务器的配置详解

一、前言 1、pig资源服务器的配置 Spring Security oauth2相关的依赖是在pigx-common-security模块中引入的&#xff0c;其他模块需要进行token鉴权的&#xff0c;需要在微服务中引入pigx-common-security模块的依赖&#xff0c;从而间接引入相关的Spring security oauth2依赖…...

vue+element ui实现图片上传并拖拽进行图片排序

用到的技术栈&#xff1a; vue2element Uivue-dragging 如何使用&#xff1a; 第一步: 安装 npm install awe-dnd --save第二步: 引入 main.js 文件 // 引入组件 import VueDND from awe-dnd // 添加至全局 Vue.use(VueDND)具体项目代码 <el-form-item label"封面…...

国产服务器 BIOS下组建RADI不同RAID卡-超详细

国产服务器 长城 组建Raid的方法 说明 大多数国产服务器通用型服务器进入BIOS的都是按DEL键。 9361RAID卡组建方法 在服务器启动过程中&#xff0c;按下DEL键进入BIOS界面。 进入设备管理器&#xff0c;选择AVAGO MegaRAID页签。 3. 进入RAID卡设备&#xff0c;选择Main Me…...

UE4 4.21-4.27使用编辑器蓝图EditorBlueprint方法

在UE4 4.21中&#xff0c;编辑器蓝图&#xff08;Editor Blueprint&#xff09;是一个强大的工具&#xff0c;允许开发者扩展和自定义Unreal编辑器的功能。通过编辑器蓝图&#xff0c;我们可以创建自定义的工具和功能&#xff0c;以优化开发流程。 本教程将指导您如何在UE4 4.…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...