1.Tabs(选项卡)

1.1 概述

Tabs组件的页面组成包含两个部分,分别是TabContent和TabBar。TabContent是内容页,TabBar是导航页签栏。
TabBar是导航页签栏,页面结构如下图所示,根据不同的导航类型,布局会有区别,可以分为底部导航、顶部导航、侧边导航,其导航栏分别位于底部、顶部和侧边。
在这里插入图片描述

1.2 基本使用

Tabs使用花括号包裹TabContent,每一个TabContent对应的内容需要有一个页签,可以通过TabContent的tabBar属性进行配置。代码如下

Tabs() {TabContent() {Text('首页的内容').fontSize(30)}.tabBar('首页')TabContent() {Text('推荐的内容').fontSize(30)}.tabBar('推荐')TabContent() {Text('发现的内容').fontSize(30)}.tabBar('发现')TabContent() {Text('我的内容').fontSize(30)}.tabBar("我的")
}

在这里插入图片描述

1.3 导航位置

barPosition 属性用来设置导航的位置,如下图所示
在这里插入图片描述

说明
● vertical为false时,tabbar的宽度默认为撑满屏幕的宽度,需要设置barWidth为合适值。
● vertical为true时,tabbar的高度默认为实际内容的高度,需要设置barHeight为合适值。

1.4 禁止滑动切换

控制滑动切换的属性为scrollable,默认值为true,表示可以滑动,若要限制滑动切换页签则需要设置为false。

Tabs({barPosition: BarPosition.Start}){...
}.scrollable(false)

1.5 滚动导航栏

当导航页签栏选项比较多时,可以让导航页签滚动
在这里插入图片描述

Tabs({ barPosition: BarPosition.Start }) {// TabContent的内容:关注、视频、游戏、数码、科技、体育、影视、人文、艺术、自然、军事...
}
.barMode(BarMode.Scrollable)

1.6 自定义导航栏

对于底部导航栏,一般作为应用主页面功能区分,为了更好的用户体验,会以“文字+图标”表示页签内容,这种情况下,需要自定义导航页签的样式。
在这里插入图片描述

1.6.1自定义导航页签

自定义导航每一个页签包含四部分内容

  1. 页签文字
  2. 页签未选中图片
  3. 页签选中时图片
  4. 页签的索引
    创建一个@Builder tabBuilder(){…}函数,用于构建自定义导航页签内容。
/*
title: 页签标题
targetIndex: 页签的索引
selectedImg: 选中时图标
normalImg: 未选中时
*/
//当前选中页签索引
@State currentIndex: number = 0
@Builder
tabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) {Column() {Image(this.currentIndex == targetIndex ? selectedImg : normalImg).size({ width: 25, height: 25 })Text(title).fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B')}.width('100%').height(50).justifyContent(FlexAlign.Center).onClick(() => {this.currentIndex = targetIndex})
}

在调用TabContent对应.tabBar(this.tabBuilder(…)),传入相对应的参数。代码如下

@Entry
@Component
struct TabsDemo {build() {Tabs({barPosition: BarPosition.End}){TabContent(){Text('首页')}.tabBar(this.tabBuilder('首页',0,$r('app.media.home_selected'),$r('app.media.home_normal')))TabContent(){Text('推荐')}.tabBar(this.tabBuilder('推荐',1,$r('app.media.home_selected'),$r('app.media.home_normal')))TabContent(){Text('热门')}.tabBar(this.tabBuilder('热门',2,$r('app.media.home_selected'),$r('app.media.home_normal')))TabContent(){Text('文化')}.tabBar(this.tabBuilder('文化',3,$r('app.media.home_selected'),$r('app.media.home_normal')))}})
}

如下图所示,此时点击页签,能够实现选中与未选中的变色效果。
在这里插入图片描述
但是此时还有一个问题,点击页签时并不能同步切换内容页。

1.6.2 点击页签同步切换内容页

想要实现点击页签同步切换页面,需要让Tabs与TabsController相关联,TabsController是用来控制页面切换的控制器,并调用TabsController的changeIndex(索引)切换内容页。

  1. 创建TabController与Tabs关联
tabsController: TabsController = new TabsController()build() {Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {... }
}
  1. 给自定义页签设置点击事件,调用TabController的changeIndex(索引)切换页签。
    在这里插入图片描述
1.6.3滑动内容页同步切换页签

在自定义导航栏的情况下,滑动内容页时,页签是不会同步切换的;此时需要监听内容页的改变,手动进行切换;

Tabs({ barPosition: BarPosition.End, controller: this.tabController }) {TabContent() {Text('首页内容')}.tabBar(this.tabBuilder('首页', 0, $r('app.media.home_selected'), $r('app.media.home_normal')))...
}.onChange((index) => {this.currentIndex = index
})

效果如下
在这里插入图片描述

2.List(列表)

2.1 基本概念

List列表是一种复杂容器,当列表项达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能。使用列表可以轻松高效地显示结构化、可滚动的信息。

在这里插入图片描述

2.2 基本使用

List和ListItem是结合起来使用的,List表示列表容器,而ListItem表示列表中的列表项。
如下图所示,这是一个最简单的列表,每一个列表项显示一个文本

在这里插入图片描述

@Entry
@Component
struct CityList {build() {List() {ListItem() {Text('北京').fontSize(24)}ListItem() {Text('杭州').fontSize(24)}ListItem() {Text('上海').fontSize(24)}}.backgroundColor('#FFF1F3F5').alignListItem(ListItemAlign.Center)}
}

2.3 循环渲染

如果List种ListItem列表项非常多,肯定不能一个一个列举,这个时候需要用到ForEach循环渲染。ForEach循环渲染的格式如下

ForEach(数据集;(元素)=>{//需要虚幻渲染的内容
})

比如我现在想要使用List列表显示中国的所有省会城市。

@Entry
@Component
struct CityList {// 定义一个字符串数组,包含中国所有的省会城市citys: string[] = ["北京","上海","天津","重庆","哈尔滨", // 黑龙江省"长春", // 吉林省"沈阳", // 辽宁省"呼和浩特", // 内蒙古自治区"石家庄", // 河北省"太原", // 山西省"西安", // 陕西省"兰州", // 甘肃省"西宁", // 青海省"银川", // 宁夏回族自治区"乌鲁木齐", // 新疆维吾尔自治区"南宁", // 广西壮族自治区"广州", // 广东省"海口", // 海南省"成都", // 四川省"贵阳", // 贵州省"昆明", // 云南省"拉萨", // 西藏自治区"郑州", // 河南省"济南", // 山东省"南京", // 江苏省"杭州", // 浙江省"合肥", // 安徽省"福州", // 福建省"台北", // 台湾省(注意:政治和实际情况可能有所不同)"南昌", // 江西省"长沙", // 湖南省"武汉",// 湖北省];build() {List() {ForEach(this.citys, (item: string) => {ListItem() {Text(item).fontSize(24)}})}.backgroundColor('#FFF1F3F5').alignListItem(ListItemAlign.Center)}
}

2.4 列表样式

  1. 设置列表项间距
List({ space: 10 }) {// ...
}
  1. 设置列表项分割线
List() {// ...
}
.divider({strokeWidth: 0.5,	//分割线的粗细color:Color.Black	//分割线的颜色
})
  1. 设置滚动条
List() {// ...
}
.scrollBar(BarState.Auto) //默认不显示,滚动时显示,2秒后消失

修改上面的案例,给列表加入自定义样式,代码如下

List({ space: 20 }) {ForEach(this.citys, (item: string) => {ListItem() {Text(item).fontSize(24)}})}.backgroundColor('#FFF1F3F5').alignListItem(ListItemAlign.Center)	//交叉轴居中显示.divider({														//加入分割线strokeWidth:1,  //线条粗细startMargin:20, //线条开始外边距endMargin:20,   //线条结尾外边距color:'#dedede'}).scrollBar(BarState.Auto) //默认不显示,滚动时显示,2秒后消失

在这里插入图片描述

2.5 复杂列表

案例需求:如下图所示是一个任务列表

  1. 每一个列表项包含:任务标题、任务创建时间、任务选中状态
  2. 点击添加时,添加列项到任务列表
  3. 点击删除时,将处于选中状态的列表项从列表中删除
  4. 点击取消时,列表项处于不可编辑状态(不显示复选框);长按列表项时,列表项处于可编辑状态(显示复选框)

在这里插入图片描述

2.5.1复杂列表的设计思路

当一个列表项显示的内容比较多时,一般会将列表项的UI和列表项的数据分离开来。如下图所示,是一个任务列表的列表项;

在这里插入图片描述

左图:用一个类来封装列表项的数据;
右图:将列表项的UI用自定义组件来表示;
合并:最后列表项的UI和数据绑定即可
多个列表项:采用ForEach循环渲染列表项就可以了

在这里插入图片描述

2.5.2 创建列表项数据模型

分析页面发现,每一个ListItem拥有三个数据,分别是:标题、创建时间、选中状态,根据编辑状态决定是否显示复选框。

class TargetItemData {title: string //目标标题createTime: string //创建时间checkStatus: boolean //选中状态  //1未选中,2选中constructor(title: string //目标标题, checkStatus: boolean //选中状态) {this.title = title;this.createTime = this.getCurrentTime();this.checkStatus = checkStatus;}//获取当前系统时间getCurrentTime(): string {let date = new Date();let year = date.getFullYear();let month = date.getMonth() + 1;let day = date.getDate();let hours = date.getHours();let minutes = date.getMinutes().toString();if (Number.parseInt(minutes) < 10) {minutes = `0${minutes}`;}let second = date.getSeconds().toString();if (Number.parseInt(second) < 10) {second = `0${second}`;}return `${year}/${month}/${day} ${hours}:${minutes}:${second}`;}
}
2.5.3 创建列表项组件

分析页面,每一个Item组件包括:一个标题Text、一个时间Text、一个复选框CheckBox;其中CheckBox根据状态决定显示或者不显示。
在这里插入图片描述

@Entry
@Component
struct Index {//2.创建Item组件,并与Item数据模型绑定@State isEditModel: number = 1 //是否编辑(1未编辑、2编辑)@BuildertargetItem(data: TargetItemData) {Row() {Column() {Text(data.title).width('100%').fontSize(18)Text(`创建时间:${data.createTime}`).fontSize(12).fontColor('#A5A6AA').margin({ top: 8 })}.alignItems(HorizontalAlign.Start).layoutWeight(9)if (this.isEditModel == 2) {Checkbox().select(data.checkStatus).layoutWeight(1).onChange((status) => {data.checkStatus = status})}}.padding({left: 12, right: 12}).backgroundColor(Color.White).height(68).border({ radius: 15 }).margin({ left: 12, right: 12 })}build() {//...}
}
2.5.4 循环渲染列表项

分析主页面的布局结构,如下图所示,我们先把中间列表这部分写出来,其他的先放一下后面再完成
在这里插入图片描述

//1.定义Item数据模型
//...@Entry
@Component
struct Index {//2.创建Item组件与Item数据模型绑定//...//3.创建Item数据集,并循环渲染到List容器中@State targets: Array<TargetItemData> = [new TargetItemData('运动', false),new TargetItemData('读书', false),new TargetItemData('听音乐', false),new TargetItemData('看电影', false),new TargetItemData('旅游', false)]build() {Column() {List({ space: 20 }) {ForEach(this.targets, (item: TargetItemData) => {ListItem() {this.targetItem(item)}})}.margin({ top: 20 })}.width('100%').height('100%').backgroundColor('#E9E9EB')}
}
2.5.5 给列表项添加长按事件

给ListItem添加长按事件,检测到手指长按时改变Item状态。

ListItem() {this.targetItem(item)
}.gesture(LongPressGesture({ duration: 500 }).onAction((event) => {this.isEditModel = 2 //编辑模式
}))
2.5.6 新增/删除列表项

当点击新增按钮时,新增一个列表项;点击删除按钮时,删除选中的列表项。
在这里插入图片描述

@Entry
@Component
struct Index {//...@State isEditModel: number = 1 //是否编辑(1未编辑、2编辑)build() {Column() {List({ space: 20 }) {//...}.margin({ top: 20 }).layoutWeight(9)		//权重9//操作按钮Column() {if (this.isEditModel == 1) {Button('新增').width('80%').onClick(() => {this.targets.push(new TargetItemData('钓鱼',false))})} else {Button('删除').width('80%').onClick(() => {let leftData = this.targets.filter((item) => item.checkStatus == false)              this.targets = leftData;this.isEditModel = 1	//设置为未编辑状态})}}.width('100%').layoutWeight(1)	//权重1.justifyContent(FlexAlign.Center)}.width('100%').height('100%').backgroundColor('#E9E9EB')}
}

3. Swiper(轮播)

3.1 基本概念

Swiper一般用来显示轮播图,在很多应用的首页都会有轮播图展示广告或者一些重要的信息。如下图所示,轮播展示几张图片。
在这里插入图片描述

3.2 基本使用

Swiper的基本使用也非常简单,只需要以下两个步骤即可
● 准备轮播数据(我这里就是4张图片,如果每一个轮播数据比较多也可以封装成对象)
● 循环渲染轮播数据
代码如下

@Entry
@Component
struct Index {//1. 准备轮播数据swiperImages: Resource[] = [$r('app.media.fig1'),$r('app.media.fig2'),$r('app.media.fig3'),$r('app.media.fig4'),]build() {Column() {Swiper() {//2.循环轮播数据ForEach(this.swiperImages, (img: Resource) => {Image(img).borderRadius(16).width('100%')})}.margin({ top: 12 }).autoPlay(true) //自动播放}.margin({left: 12, right: 12})}
}

3.3 导航点指示器

Swiper(){ForEach(this.imageArray,(item:Resource)=>{Image(item).width('100%').height(200).borderRadius(10)})
}
//.indicator(false)  true表示有导航点、false表示没有导航点
.indicator(//Indicator.digit() //数字导航指示效果Indicator.dot() //原点导航点.itemWidth(20)  //未选中的宽度.selectedItemWidth(20)  //选中的宽度.color(Color.Red) //未选中的颜色.selectedColor(Color.Yellow)  //选中的颜色
)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/95237.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95237.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/95237.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt5 多媒体大纲

一、入门准备 基础知识 熟悉 Qt 的信号槽机制、事件循环 掌握 .pro 工程文件配置&#xff08;QT multimedia multimediawidgets&#xff09; 熟悉常见的音视频格式与编解码器基础 环境配置 Qt Creator Qt 5.x 确认安装了 multimedia 模块与 mediaservice 插件 熟悉调试…

音频数据集采样率选择建议

你好&#xff01;这是一个非常棒且非常重要的问题&#xff0c;在音频机器学习项目中&#xff0c;选择合适的采样率是平衡计算效率和模型性能的关键。 直接回答你的问题&#xff1a;将音频下采样到 800 Hz 对于绝大多数音频分类任务来说都太低了&#xff0c;几乎肯定会丢失大量关…

深度学习系列 | Seq2Seq端到端翻译模型

一、通俗总结Seq2Seq 就像一个 “序列转换器”&#xff1a;先把输入的一段话 “压缩成一个核心意思”&#xff0c;再根据这个意思 “一句句生成另一段话”&#xff0c;能搞定翻译、听写这类 “输入输出不一样长” 的任务&#xff0c;但太长的内容可能记不全&#xff0c;还容易越…

Spring MVC BOOT 中体现的设计模式

Spring:创建型:单例模式:Bean默认就是单例的&#xff0c;是饿汉模式的&#xff0c;但是可以通过Lazy设置为懒汉工厂模式&#xff1a;可自定义FactroyBean&#xff0c;实现Bean自己的生产工厂结构型:代理模式&#xff1a;AOP就是典型的动态代理&#xff0c;有jdk和cglib两种实现…

Chrome浏览器调用ActiveX控件之allWebOffice在线编辑控件

背景 allWebOffice控件能够实现在浏览器窗口中在线操作文档的应用&#xff08;阅读、编辑、保存等&#xff09;&#xff0c;支持编辑文档时保留修改痕迹&#xff0c;支持书签位置内容动态填充&#xff0c;支持公文套红&#xff0c;支持文档保护控制等诸多办公功能&#xff0c;本…

嵌入式 - 硬件:51单片机

本节重点1. MCU、CPU、GPU、NPU、SOC、MPU、FPU2. 内存、外存的区别3. RAM和ROM的区别&#xff0c;单片机RAM大小4. 三大总线及其特点5. 发光二极管分类及其特点6. 数码管显示原理一、嵌入式以应用为中心&#xff0c;以计算机技术为基础&#xff0c;软硬件可裁剪的专用计算机系…

Java Spring Boot 中 Redis 缓存穿透问题排查与解决方案

前言 作为一名普通的 Java 程序开发者&#xff0c;日常开发中难免会遇到一些看似简单但实际排查起来非常棘手的问题。在最近的一个项目中&#xff0c;我遇到了一个 Redis 缓存穿透的问题&#xff0c;导致系统在高并发下性能急剧下降&#xff0c;甚至出现服务响应超时的情况。这…

Ubuntu下配置并远程连接MySQL

1、安装mysql-serverapt update apt install mysql-server2、修改配置文件/etc/mysql/mysql.conf.d/mysqld.cnfbind-address 0.0.0.0 mysqlx-bind-address 0.0.0.03、启动并设置服务为开机自启动systemctl enable mysql.service --now4、查看服务状态systemct…

开源 C++ QT Widget 开发(九)图表--仪表盘

文章的目的为了记录使用C 进行QT Widget 开发学习的经历。临时学习&#xff0c;完成app的开发。开发流程和要点有些记忆模糊&#xff0c;赶紧记录&#xff0c;防止忘记。 相关链接&#xff1a; 开源 C QT Widget 开发&#xff08;一&#xff09;工程文件结构-CSDN博客 开源…

怎么为服务器设置或重置服务器密码?

创建服务器后&#xff0c;您可以设置服务器的登录密码&#xff0c;如果你忘记了密码&#xff0c;可以重新设置实例的密码。本文讲一下如何重置阿里云服务器密码。使用限制&#xff1a;离线重置密码仅支持在控制台设置或重置服务器管理员账号的密码。•Windows 实例的默认用户名…

【线性代数入门 | 那忘算8】洛谷P3389 高斯消元(内附行列式教学)

想了想还是单开了一篇&#xff0c;数学王子值得&#xff01; 专栏指路&#xff1a;《再来一遍一定记住的算法&#xff08;那些你可能忘记了的算法&#xff09;》 前置知识&#xff1a; 矩阵&#xff1a;数的集合&#xff0c;一般是方程的系数。 题面&#xff1a; 洛谷P3389 …

GEM5学习(3):如何快速创建一个组件

通过一个图并行计算的测试用例&#xff0c;来学习如何快速构建一个目标组件 其核心思想是通过继承现有组件再拓展自定义参数 创建脚本 如何创建脚本&#xff0c;具体还可以看官方说明&#xff1a;gem5: Adding cache to configuration script mkdir configs/tutorial/part1/…

数据血缘中的图数据库如何选择

Neo4j 和 ArangoDB 都是非常优秀的图数据库&#xff0c;但它们的设计哲学、核心架构和适用场景有显著的区别。 简单来说&#xff0c;核心区别在于&#xff1a; Neo4j 是原生图数据库&#xff0c;专为处理图数据和图查询而设计和优化。ArangoDB 是多模型数据库&#xff0c;同时支…

第27章学习笔记|学无止境:从“会用命令”到“会做工具”的进阶路线

第27章学习笔记|学无止境:从“会用命令”到“会做工具”的进阶路线 你已经能用 PowerShell 解决很多日常问题了。接下来最重要的,就是把零散命令升级为可复用的工具,并在真实场景中不断打磨。 一、为什么下一步是“工具化(Toolmaking)” 当任务开始“重复、多人用、可移…

C++编程语言:标准库:第37章——正则表达式(Bjarne Stroustrup)

第 37章 正则表达式(Regular Expressions) 目录 37.1 正则表达式(规范表达式)(Regular Expressions) 37.1.1 正则表达式相关符号(Regular Express Notation) 37.2 regex 37.2.1 匹配结果(Match Results) 37.2.2 格式化(Formatting) 37.3 正则表达式函数 37.3.1 …

sciml包scixgboost函数发布,轻松完成机器学习xgboost分析

Xgboost是Boosting算法的其中一种&#xff0c;Boosting算法的思想是将许多弱分类器集成在一起&#xff0c;形成一个强分类器。因为Xgboost是一种提升树模型&#xff0c;所以它是将许多树模型集成在一起&#xff0c;形成一个很强的分类器。 我目前整合了多个R包&#xff0c;编写…

Ubuntu中配置JMmeter工具

1、检查是否已安装Java 环境java -version若未安装&#xff0c;执行以下命令安装 OpenJDKsudo apt update sudo apt install openjdk-11-jdk # 或 openjdk-17-jdk2、用wget直接下载JMeter压缩包wget https://dlcdn.apache.org/jmeter/binaries/apache-jmeter-5.6.3.tgz将下载的…

LeetCode 925.长按键入

你的朋友正在使用键盘输入他的名字 name。偶尔&#xff0c;在键入字符 c 时&#xff0c;按键可能会被长按&#xff0c;而字符可能被输入 1 次或多次。 你将会检查键盘输入的字符 typed。如果它对应的可能是你的朋友的名字&#xff08;其中一些字符可能被长按&#xff09;&#…

9.3 模拟

lc190 颠倒二进制ret (ret << 1) (n >> i & 1);class Solution { public:uint32_t reverseBits(uint32_t n) {uint32_t ret 0;for (int i 0; i < 32; i)ret (ret << 1) (n >> i & 1);return ret;} };lc14 flag checkclass Solution {…

esp32小智ai对话机器人

ESP-IDF 环境搭建与问题解决 下载与安装 ESP-IDF 官方下载地址&#xff1a;https://dl.espressif.com/dl/esp-idf建议使用稳定版本&#xff0c;避免开发版可能存在的兼容性问题 中文编码问题解决方案 $env:PYTHONIOENCODING "utf-8" $env:PYTHONUTF8 "1&q…