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

鸿蒙Next如何自定义标签页

前言

项目需求是展示标签,标签的个数不定,一行展示不行就自行换行。但是,使用鸿蒙原生的 Grid 后发现特别的难看。然后就想着自定义控件。找了官方文档,发现2个重要的实现方法,但是,官方的demo中讲的很少,需要自己去看去思考。

效果图如下:
在这里插入图片描述
注意点:

  1. 需要计算整体布局的宽高,这和 Android 差不多。
  2. 注意 margin 的计算

具体的代码如下:

/*** 自定义标签页面*/
@Component struct CustomTagView {screenWidth: number = 0aboutToAppear(): void {let dis = display.getDefaultDisplaySync();let width = dis.widthlet height = dis.height// width 是单位是 px, 转换为 vp ,因为 onMeasureSize 和 onPlaceChildren 得到的 width margin 以及 padding 都是 vplet w = px2vp(width)let h = px2vp(height)this.screenWidth = wconsole.log("TagView aboutToAppear width = " + width + " , height = " + height + ", w = " + w + ", h = " + h)}@Builder childBuilder() {}@BuilderParam buildTagView: () => void = this.childBuilderresult: SizeResult = {width: 0,height: 0}// 第一步:计算各子组件的实际大小以及设置布局本身的大小onMeasureSize(selfLayoutInfo: GeometryInfo, children: Array<Measurable>, constraint: ConstraintSizeOptions) {let parentWidth = selfLayoutInfo.widthlet parentHeight = selfLayoutInfo.heightconsole.log("TagView onMeasureSize parentWidth = " + parentWidth + " , parentHeight = " + parentHeight)let startPosX = 0let columNumber = 1let childHeight = 0children.forEach((child) => {// 得到子控件的实际大小let result: MeasureResult = child.measure({minHeight: constraint.minHeight,minWidth: constraint.minWidth,maxWidth: constraint.maxWidth,maxHeight: constraint.maxHeight})let padding = child.getPadding()let border = child.getBorderWidth()console.log("TagView onMeasureSize = child width = " + result.width + "  ,  height = " + result.height+ " , padding = [" + padding.start + ", " + padding.end + ", " + padding.top + ", " + padding.bottom +"], border = ["+ border.start + ", " + border.end + ", " + border.top + ", " + border.bottom + "]")/// 计算 布局所需的高度, 宽度默认为屏幕的宽度childHeight = result.height + child.getMargin().topstartPosX += result.width + child.getMargin().startif (startPosX > parentWidth) {columNumber++startPosX = result.width + child.getMargin().start}})// 父布局的宽和高,即承载 child 布局的宽和高,这里指的就是 TagView 的宽和高this.result.width = this.screenWidth;this.result.height = childHeight * columNumber + 10 // 加10是为了底部多点空间return this.result;}// 第二步:放置各子组件的位置onPlaceChildren(selfLayoutInfo: GeometryInfo, children: Array<Layoutable>, constraint: ConstraintSizeOptions) {let startPosX = 0let startPosY = 0let posY = 0let parentWidth = selfLayoutInfo.widthconsole.log("TagView onPlaceChildren parentWidth = " + selfLayoutInfo.width + " , parentHeight = " + selfLayoutInfo.height)children.forEach((child) => {startPosX += child.getMargin().start// 如果一行的控件的长度大于屏幕宽度则换行if (startPosX + child.measureResult.width > parentWidth) {startPosY += child.measureResult.height + child.getMargin().topstartPosX = child.getMargin().start}posY = startPosYconsole.log("TagView child width = " + child.measureResult.width + "  ,  height = " + child.measureResult.height +" , margin left = " + child.getMargin().start)child.layout({ x: startPosX, y: posY })startPosX += child.measureResult.width})}build() {this.buildTagView()}
}
调用的方法也很简单,下面是个调用的demo
@Entry
@Component
struct TestPage {@State name: string = 'hello'// @Provide 参数 key 必须是 string@Provide('provideName') pName: string = "哈哈"@Provide('count') count: number = 4textWidth: number = 0aboutToAppear(): void {let width = MeasureText.measureText({ textContent: '返厂无忧券1', fontSize: '13vp' });let w = px2vp(width)console.log("TestPage aboutToAppear >>>> width = " + width + " , w = " + w)// 如果有换行,那么长度等于最长的一行let textSize = MeasureText.measureTextSize({ textContent: '返厂无忧券1\n返厂无忧券1234', fontSize: '13vp' })let w2 = textSize.widthlet h2 = textSize.heightthis.textWidth = px2vp(w2 as number)console.log("TestPage aboutToAppear >>>> w2 = " + w2 + " , h2 = " + h2)}// @Build 参数按值传递,状态变量改变不会引起 @Build 方法内的 UI 刷新// 但是,Text(" ----- " + this.name) 中的 UI 会刷新@BuildernameView(name: string) {Text(name)}//  @Build 参数按引用传递的话,状态变量(@State name) 改变,@Build 方法内的 UI 会刷新@BuildernameView2(tmp: Tmp) {Text('V2 : name = ' + tmp.params)}// 通过builder的方式传递多个组件,作为自定义组件的一级子组件(即不包含容器组件,如Column)@BuilderTagViewChildren() {ForEach(['你好,哪吒2', '大圣归来啊', '我是名字超长的但是很厉害', 'hello world', '你真的好厉害啊哈哈', '没空看', '非凡','再来一个很长的名字啊', 'OK'],(data: string, index: number) => { // 暂不支持lazyForEach的写法Text(data).fontSize(13).fontColor(Color.Red).margin({ left: 3, top: 4 })// .width(100)// .height(100).borderWidth(1).border({ radius: 4 }).padding(5).textAlign(TextAlign.Center)// .offset({ x: 10, y: 20 })})}build() {Column() {Column() {CustomTagView({ buildTagView: this.TagViewChildren })}.backgroundColor(Color.Pink).margin({ top: 2 })}.width('100%').height('100%').alignItems(HorizontalAlign.Start)}
}

好了,具体的可以参考下 demo 啦,有疑问的可以一起交流。

相关文章:

鸿蒙Next如何自定义标签页

前言 项目需求是展示标签&#xff0c;标签的个数不定&#xff0c;一行展示不行就自行换行。但是&#xff0c;使用鸿蒙原生的 Grid 后发现特别的难看。然后就想着自定义控件。找了官方文档&#xff0c;发现2个重要的实现方法&#xff0c;但是&#xff0c;官方的demo中讲的很少&…...

知识拓展:Python 接口实现方式对比:Protocol vs @implementer

Python 接口实现方式对比&#xff1a;Protocol vs implementer 1. 两种接口实现方式 1.1 Python Protocol&#xff08;结构化子类型&#xff09; from typing import Protocolclass DownloadHandlerProtocol(Protocol):def download_request(self, request: Request, spider:…...

开源程序wordpress在海外品牌推广中的重要作用

WordPress作为全球最流行的开源内容管理系统(CMS)&#xff0c;在全球网站搭建中占据超过40%的市场份额。其强大的功能、灵活性和易用性使其成为企业进行海外品牌推广的首选平台。以下是WordPress在海外品牌推广中的重要性分析&#xff1a; 1. 多语言支持与本地化 WordPress通…...

【Python爬虫(89)】爬虫“反水”:助力数字版权保护的逆向之旅

【Python爬虫】专栏简介&#xff1a;本专栏是 Python 爬虫领域的集大成之作&#xff0c;共 100 章节。从 Python 基础语法、爬虫入门知识讲起&#xff0c;深入探讨反爬虫、多线程、分布式等进阶技术。以大量实例为支撑&#xff0c;覆盖网页、图片、音频等各类数据爬取&#xff…...

k8s面试题总结(五)

1.考虑一种情况&#xff0c;即公司希望通过维持最低成本来提高其效率和技术运营速度。您认为公司将如何实现这一目标&#xff1f; 公司可以通过构建 CI/CD 管道来实现 DevOps 方法&#xff0c;但是这里可能出现的一个问题是配置可能需要一段时间才能启动并运行。 因此&#x…...

文章精读篇——用于遥感小样本语义分割的可学习Prompt

题目&#xff1a;Learnable Prompt for Few-Shot Semantic Segmentation in Remote Sensing Domain 会议&#xff1a;CVPR 2024 Workshop 论文&#xff1a;10.48550/arXiv.2404.10307 相关竞赛&#xff1a;https://codalab.lisn.upsaclay.fr/competitions/17568 年份&#…...

Spring Boot2.0之十 使用自定义注解、Json序列化器实现自动转换字典类型字段

前言 项目中经常需要后端将字典类型字段值的中文名称返回给前端。通过sql中关联字典表或者自定义函数不仅影响性能还不能使用mybatisplus自带的查询方法&#xff0c;所以推荐使用自定义注解、Json序列化器&#xff0c;Spring的缓存功能实现自动转换字典类型字段。以下实现Spri…...

从电子管到量子计算:计算机技术的未来趋势

计算机发展的历史 自古以来人类就在不断地发明和改进计算工具,从结绳计数到算盘,计算尺,手摇计算机,直到1946年第一台电子计算机诞生,虽然电子计算机至今虽然只有短短的半个多世纪,但取得了惊人的发展吗,已经经历了五代的变革。计算机的发展和电子技术的发展密切相关,…...

将CUBE或3DL LUT转换为PNG图像

概述 在大部分情况下&#xff0c;LUT 文件通常为 CUBE 或 3DL 格式。但是我们在 OpenGL Shader 中使用的LUT&#xff0c;通常是图像格式的 LUT 文件。下面&#xff0c;我将教大家如何将这些文件转换为 PNG 图像格式。 条形LUT在线转换&#xff08;不是8x8网络&#xff09;&am…...

python文件的基本操作,文件读写

1.文件 1.1文件就是存储在某种长期存储设备上的一段数据 1.2文件操作 打开文件-->读写文件-->关闭文件 注意&#xff1a;可以只打开和关闭文件不进行任何操作 1.3文件对象的方法 1.open():创建一个file对象&#xff0c;默认以只读模式打开 2.read(n):n表示从文件中…...

华为认证考试证书下载步骤(纸质+电子版)

华为考试证书可以通过官方渠道下载相应的电子证书&#xff0c;部分高级认证如HCIE还支持申请纸质证书。 一、华为电子版证书申请步骤如下&#xff1a; ①访问华为培训与认证网站 打开浏览器&#xff0c;登录华为培训与认证官方网站 ②登录个人账号 在网站首页&#xff0c;点…...

正式页面开发-登录注册页面

整体路由设计&#xff1a; 登录和注册的切换是切换组件或者是切换内容&#xff08;v-if和 v-else)&#xff0c;因为点击两个之间路径是没有变化的。也就是登录和注册共用同一个路由。登录是独立的一级路由。登录之后进到首页&#xff0c;有三个大模块&#xff1a;文章分类&…...

nss刷题5(misc)

[HUBUCTF 2022 新生赛]最简单的misc 打开后是一张图片&#xff0c;没有其他东西&#xff0c;分离不出来&#xff0c;看看lsb&#xff0c;红绿蓝都是0&#xff0c;看到头是png&#xff0c;重新保存为png&#xff0c;得到一张二维码 扫码得到flag [羊城杯 2021]签到题 是个动图…...

深入Linux序列:进程的终止与等待

在之前的学习中&#xff0c;我们知道我们的进程在运行结束的时候&#xff0c;那么它并不会立即进入死亡状态&#xff0c;而是先进入僵尸状态&#xff0c;维持僵尸状态一段时间&#xff0c;那么此时在僵尸状态中的进程&#xff0c;那么它的内核数据已经移出内存被清理了&#xf…...

蓝桥杯之日期问题2

文章目录 需求11.1 代码 2.需求22.1代码 需求1 2020 年春节期间&#xff0c;有一个特殊的日期引起了大家的注意&#xff1a;2020 年 2 月 2 日。因为如果将这个日期按 “yyyymmdd” 的格式写成一个 8 位数是 20200202&#xff0c;恰好是一个回文数。我们称这样的日期是回文日期…...

【STL】7.STL常用算法(1)

STL常用算法&#xff08;1&#xff09; 前言简介一.遍历算法1.for_each2.transform 二.查找算法1.find2.find_if3.adjacent_find4.binary_search5.count6.cout_if 三.排序算法1.sort2.random_shuffle3.merge4.reverse 总结 前言 stl系列主要讲述有关stl的文章&#xff0c;使用S…...

uniapp 本地数据库多端适配实例(根据运行环境自动选择适配器)

项目有个需求&#xff0c;需要生成app和小程序&#xff0c;app支持离线数据库&#xff0c;如果当前没有网络提醒用户开启离线模式&#xff0c;所以就随便搞了下&#xff0c;具体的思路就是&#xff1a; 一个接口和多个实现类&#xff08;类似后端的模板设计模式&#xff09;&am…...

百度觉醒,李彦宏渴望光荣

文 | 大力财经 作者 | 魏力 2025年刚刚开年&#xff0c;被一家名为DeepSeek的初创公司强势改写。在量化交易出身的创始人梁文锋的带领下&#xff0c;这支团队以不到ChatGPT 6%的训练成本&#xff0c;成功推出了性能可与OpenAI媲美的开源大模型。 此成果一经问世&#xff0c;…...

【算法工程】大模型局限性新发现之解决能连github但无法clone项目的问题

最近&#xff0c;linux服务器遇到一个奇怪的问题&#xff0c;能ping通github&#xff0c;但是无法clone git项目&#xff0c;尝试了各种大模型&#xff0c;都提到代理啥的问题&#xff0c;发现没有一个能解决问题。 后来尝试设置 http.sslVerify 为 false&#xff0c;才解决问题…...

SOME/IP-SD -- 协议英文原文讲解3

前言 SOME/IP协议越来越多的用于汽车电子行业中&#xff0c;关于协议详细完全的中文资料却没有&#xff0c;所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块&#xff1a; 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 5.1.2.4…...

从零构建AI辅助逆向分析环境:JADX-MCP与LLM的实战集成指南

1. 为什么需要AI辅助逆向分析&#xff1f; 逆向工程一直是安全研究员和开发者的重要技能&#xff0c;但面对日益复杂的Android应用&#xff0c;传统的手工分析方式效率低下。一个中等规模的APK反编译后可能产生数万行代码&#xff0c;人工阅读这些代码就像大海捞针。我曾经分析…...

HunyuanVideo-Foley 模型服务容器化:使用Docker Compose编排多组件依赖

HunyuanVideo-Foley 模型服务容器化&#xff1a;使用Docker Compose编排多组件依赖 1. 引言 想象一下&#xff0c;你正在开发一个智能音效生成平台&#xff0c;需要同时管理AI模型服务、数据库和缓存系统。每次启动都要手动配置多个组件&#xff0c;不仅耗时还容易出错。这就…...

深入解析rviz中基于MVC架构的点云3D坐标拾取机制

1. 为什么rviz没有直接使用OpenGL的坐标拾取API&#xff1f; 第一次接触rviz源码时&#xff0c;我下意识认为它肯定直接调用了gluUnProject这类OpenGL原生API来实现3D坐标拾取。毕竟在常规图形学开发中&#xff0c;这就像喝水一样自然——用现成的API不香吗&#xff1f;但当我…...

忍者像素绘卷:天界画坊LSTM时间序列分析应用:预测用户绘画风格偏好

忍者像素绘卷&#xff1a;天界画坊LSTM时间序列分析应用 1. 场景痛点&#xff1a;AI绘画平台的用户偏好捕捉难题 在AI绘画平台"天界画坊"的运营过程中&#xff0c;我们发现一个普遍存在的痛点&#xff1a;用户风格偏好的动态变化难以捕捉。传统推荐系统主要基于静态…...

别再手动写SFTP工具类了!用Hutool 5.8.26 + JSch搞定文件传输,附完整代码和并发避坑指南

HutoolJSch实现高效SFTP文件传输&#xff1a;从基础到高并发实战 如果你还在为Java项目中的SFTP文件传输重复编写工具类&#xff0c;是时候解放双手了。Hutool 5.8.26结合JSch提供的SFTP封装&#xff0c;不仅能减少90%的样板代码&#xff0c;还能避免那些只有踩过坑才知道的并发…...

如何构建高效跨设备键鼠共享系统:Lan Mouse终极指南

如何构建高效跨设备键鼠共享系统&#xff1a;Lan Mouse终极指南 【免费下载链接】lan-mouse mouse & keyboard sharing via LAN 项目地址: https://gitcode.com/gh_mirrors/la/lan-mouse 在当今多设备协同的工作环境中&#xff0c;跨设备键鼠共享技术已成为提升工作…...

CISCN2024 Web赛题实战复盘:从命令执行到沙箱逃逸的攻防博弈

1. 从命令执行到沙箱逃逸的攻防博弈 CISCN2024的Web赛题设计非常贴近实战&#xff0c;考察了选手从基础漏洞挖掘到高级利用技巧的全方位能力。这次比赛中的几个典型题目&#xff0c;完美展现了Web安全攻防中的经典场景和最新技术趋势。 在实战中&#xff0c;我们经常会遇到各种…...

CLIP模型调优新思路:用CoCoOp实现动态提示学习(附代码实战)

CLIP模型调优新思路&#xff1a;用CoCoOp实现动态提示学习&#xff08;附代码实战&#xff09; 在计算机视觉与自然语言处理的交叉领域&#xff0c;视觉语言模型正掀起一场革命。CLIP作为这一领域的里程碑式模型&#xff0c;通过对比学习将图像和文本映射到同一语义空间&#x…...

WeKnora快速上手:5分钟搭建零幻觉问答系统

WeKnora快速上手&#xff1a;5分钟搭建零幻觉问答系统 1. 为什么选择WeKnora问答系统 在日常工作和学习中&#xff0c;我们经常遇到这样的情况&#xff1a;需要从大段文本中快速找到特定信息&#xff0c;或者确保AI回答完全基于我们提供的资料。传统AI聊天工具虽然方便&#…...

百川2-13B对话模型一键部署:Python环境配置与快速启动指南

百川2-13B对话模型一键部署&#xff1a;Python环境配置与快速启动指南 想试试最新的开源大模型&#xff0c;却被复杂的Python环境、CUDA版本、依赖冲突搞得头大&#xff1f;这几乎是每个AI开发者入门时都会遇到的“劝退”第一关。今天&#xff0c;我们就来彻底解决这个问题。我…...