【每日学点鸿蒙知识】PersistentStorage持久化、插槽方法、相对布局、上拉加载下拉刷新、List联动滑动

devtools/2024/12/29 9:49:31/
1、HarmonyOS 使用PersistentStorage持久化用户信息无效?

在首页通过@StorageLink(‘userInfoTest’) userInfoTest: string = ''获取,获不到,返回undefind。是什么原因呢?

首先在首页时,在Entry外声明PersistentStorage.persistProp,其次在登录完成设置值时不使用PersistentStorage.persistProp而是使用AppStorage.set来修改值。下面以userInfo为例:

PersistentStorage.persistProp('userInfo',"111") //可以直接放在import代码下方,此处只以userInfo为例,每一个需要持久化保存的都需要声明
//声明时设置的值可以任意,后续通过set修改,j尽量和目标值保持属性一致
@Entry
@Component
struct Index {build() {Column(){Button("点击测试").onClick(()=>{console.log("测试set")AppStorage.set('userInfo', "ceshi") //直接使用AppStorage.set,而非PersistentStorage.persistProp,否则将无法修改})Button("查找userInfo").onClick(()=>{const ut = AppStorage.get<string>('userInfo')console.log(ut); //测试结果显示userInfo中存的值变成了"ceshi",杀进程,重新进入后直接点击button,log的结果依旧是"ceshi",实现持久化存储})}}
}
2、HarmonyOS 有像 Vue 一样的插槽使用方法吗?

可以使用@BuilderParam装饰器,该装饰器用于声明任意UI描述的一个元素,类似slot占位符。参考链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-builderparam-V5

3、HarmonyOS RelativeContainer 经过offset设置的锚点位置坐标不能作为锚点,只能用没有经过offset配置的旧坐标作为锚点来给下一个组件进行标定?

比如说A组件经过了锚点配置了位置,此时A组件有一个坐标pos1,经过offset设置了新的位置pos2,B组件想要基于A的新位置pos2做标定,必须要将A组件的offset一并加上才能达到在pos2基础上做标定。

比如说下面三个组件,想要达成的效果是年龄和个人信息之间相差13,性别和年龄之间间隔13,但是实际上却是这三个组件之间的间隔为0

Row() {Text('个人信息').fontColor(Color.White).fontSize(14).alignRules({left: { anchor: 'row1', align: HorizontalAlign.Start },center: { anchor: 'row1', align: VerticalAlign.Center }}).offset({x: 13,y: 0,}).id("person_info_text")Button('年龄').fontSize(12).aspectRatio(1.857).alignRules({left: { anchor: "person_info_text", align: HorizontalAlign.End },center: { anchor: 'row1', align: VerticalAlign.Center }}).offset({x: 13,y: 0,}).id("age_btn")Button('性别').fontSize(12).aspectRatio(1.857).alignRules({left: { anchor: "age_btn", align: HorizontalAlign.End },center: { anchor: 'row1', align: VerticalAlign.Center }}).offset({x: 13,y: 0,}).id("gender_btn")

RelativeContainer经过offset设置的锚点位置还是之前没有偏移的位置,所以后面的组件参考的位置还是偏移前的位置,所以要实现上面的效果需要这样设置:

.offset({x: 13,y: 0,
}).offset({x: 26,y: 0,}).offset({x: 39,y: 0,})
4、HarmonyOS 上拉加载下拉刷新的控件有没有已经封装好了的?

数据请求写在listTouchEvent里,关联性太强,需要一个封装好,把上拉下拉布局暴露在外由用户设定,监听也有的。

PullToRefresh可用的下拉刷新、上拉加载组件。可参考链接:https://gitee.com/openharmony-sig/ohos_pull_to_refresh

demo如下:

import { PullToRefresh } from '@ohos/pulltorefresh'@Entry
@Component
struct Index {@State refreshText: string = '';private dataNumbers: string[] = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'];private dataStrings: string[] =['我的评论', '与我相关', '个人中心1', '个人中心2', '个人中心3', '我的发布', '设置', '退出登录'];@State data: string[] = this.dataStrings;// 需绑定列表或宫格组件private scroller: Scroller = new Scroller();build() {Column() {PullToRefresh({// 必传项,列表组件所绑定的数据data: $data,// 必传项,需绑定传入主体布局内的列表或宫格组件scroller: this.scroller,// 必传项,自定义主体布局,内部有列表或宫格组件customList: () => {// 一个用@Builder修饰过的UI方法this.getListView();},// 可选项,下拉刷新回调onRefresh: () => {return new Promise<string>((resolve, reject) => {// 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据setTimeout(() => {resolve('刷新成功');this.data = this.dataNumbers;}, 2000);});},// 可选项,上拉加载更多回调onLoadMore: () => {return new Promise<string>((resolve, reject) => {// 模拟网络请求操作,请求网络2秒后得到数据,通知组件,变更列表数据setTimeout(() => {resolve('');this.data.push("增加的条目" + this.data.length);}, 2000);});},customLoad: null,customRefresh: null,})}}@Builderprivate getListView() {List({ space: 20, scroller: this.scroller }) {ForEach(this.data, (item: string) => {ListItem() {Text(item).width(160).height(150).fontSize(20).textAlign(TextAlign.Center).backgroundColor('#95efd2')}})}.backgroundColor('#eeeeee').divider({ strokeWidth: 1, color: 0x222222 }).edgeEffect(EdgeEffect.None) // 必须设置列表为滑动到边缘无效果}
}
5、HarmonyOS List联动滑动?

有个页面需要两个List联动,且第一个List需要吸顶,但使用ListItemGroup做吸顶功能后,由于Index变成Apis文档中说的:ListItemGroup作为一个整体计算一个索引值,ListItemGroup内部的ListItem不计算索引值。导致两个List不再能根据Index联动.

demo示例如下:

// 商品顶部分类
interface CategoriesType {current: string[],hot: string[],Categories: Map<string, Category[]>
}interface Category {code: string;category: string;
}@Entry
@Component
export default  struct CityList{private currentCategory: string = ''private hotCategories: string[] = []private groupCategories: Map<string, Category[]> = new Mapprivate groupNameList: string[] = ['A区', 'B区', 'C区', 'D区', 'F区', 'G区', 'H区', 'J区', 'K区', 'L区']@State private selectGroupIndex: number = -1private categoryScroller: ListScroller = new ListScroller()private categoryScroller1: ListScroller = new ListScroller()private isClickScroll:boolean = falseaboutToAppear() {let jsonString: string = '{"current":["保健品专区"],"hot":["险种转换","保单挂失","保单补发"],"Categories":{"A区":[{"code":"001","category":"新增附加险"},{"code":"002","category":"保险附效1"},{"code":"003","category":"保险附效2"},{"code":"004","category":"保险附效3"},{"code":"005","category":"保险附效4"},{"code":"006","category":"保险附效5"},{"code":"007","category":"保险附效6"}],"B区":[{"code":"008","category":"保险附效1"},{"code":"009","category":"保险附效2"},{"code":"012","category":"保险附效3"}],"C区":[{"code":"008","category":"保险附效1"},{"code":"009","category":"保险附效2"},{"code":"010","category":"保险附效3"},{"code":"011","category":"保险附效4"},{"code":"012","category":"保险附效5"}],"D区":[{"code":"008","category":"保险附效1"},{"code":"009","category":"保险附效2"},{"code":"010","category":"保险附效3"},{"code":"011","category":"保险附效4"},{"code":"012","category":"保险附效5"}],"E区":[{"code":"008","category":"保险附效1"},{"code":"009","category":"保险附效2"},{"code":"010","category":"保险附效3"},{"code":"011","category":"保险附效4"},{"code":"012","category":"保险附效5"}],"F区":[{"code":"008","category":"保险附效1"},{"code":"009","category":"保险附效2"},{"code":"010","category":"保险附效3"},{"code":"011","category":"保险附效4"},{"code":"012","category":"保险附效5"}],"G区":[{"code":"008","category":"保险附效1"},{"code":"009","category":"保险附效2"},{"code":"010","category":"保险附效3"},{"code":"011","category":"保险附效4"},{"code":"012","category":"保险附效5"}],"H区":[{"code":"008","category":"保险附效1"},{"code":"009","category":"保险附效2"},{"code":"010","category":"保险附效3"},{"code":"011","category":"保险附效4"},{"code":"012","category":"保险附效5"}],"J区":[{"code":"008","category":"保险附效1"},{"code":"009","category":"保险附效2"},{"code":"010","category":"保险附效3"},{"code":"011","category":"保险附效4"},{"code":"012","category":"保险附效5"}],"K区":[{"code":"008","category":"保险附效1"},{"code":"009","category":"保险附效2"},{"code":"010","category":"保险附效3"},{"code":"011","category":"保险附效4"},{"code":"012","category":"保险附效5"}],"L区":[{"code":"008","category":"保险附效1"},{"code":"009","category":"保险附效2"},{"code":"010","category":"保险附效3"},{"code":"011","category":"保险附效4"},{"code":"012","category":"保险附效5"}]}}'let data: CategoriesType = JSON.parse(jsonString) as CategoriesTypethis.currentCategory = data.current[0]this.hotCategories = data.hotthis.groupCategories = data.Categoriesconsole.log('fxm = ', JSON.stringify(this.groupCategories['A区']))}build() {Column() {Row() {this.navigationList()}.width('100%').height(42)Column() {this.categoryList()}.height('100%')}}getCitiesWithGroupName(name: string): Category[] {console.log('fxm ', this.groupCategories[name])return this.groupCategories[name]}@BuilderitemHead(text: string) {Text(text).fontSize(16).width("100%").padding({ left: 10 }).height(45).backgroundColor(0xEEEEEE)}@BuildercategoryList() {List({ scroller: this.categoryScroller }) {ListItemGroup({ header: this.itemHead('当前专区') }) {ListItem() {Text(this.currentCategory).width("100%").height(45).fontSize(16).textAlign(TextAlign.Start).backgroundColor(0xFFFFFF).padding({ left: 10 })}}ListItemGroup({ header: this.itemHead('热门专区') }) {ForEach(this.hotCategories, (hotCategory: string) => {ListItem() {Text(hotCategory).width("100%").height(45).fontSize(16).textAlign(TextAlign.Start).backgroundColor(0xFFFFFF).padding({ left: 10 })}})}// A~L专区分组ForEach(this.groupNameList, (item: string) => {ListItemGroup({ header: this.itemHead(item) }) {ForEach(this.getCitiesWithGroupName(item), (item: Category) => {ListItem() {Text(item.category).width("100%").height(45).fontSize(16).textAlign(TextAlign.Start).backgroundColor(0xFFFFFF).padding({ left: 10 })}}, (item: Category) => item.category)}})}.width('100%').height('100%').scrollBar(BarState.Off).sticky(StickyStyle.Header).onTouch(()=>{// 分区列表触摸滚动,isClickScroll=false,防止滚动过程中与导航列表触发滚动冲突this.isClickScroll = false}).onScrollIndex((start: number, end: number, center: number)=>{// 通过selectGroupIndex状态变量与start联动控制导航列表选中状态if(!this.isClickScroll)this.selectGroupIndex = start - 2})}@BuildernavigationList() {List({scroller:this.categoryScroller1}) {ForEach(this.groupNameList, (item: string, index: number) => {ListItem() {Text(item).width(42).height(30).fontSize(16).textAlign(TextAlign.Start).backgroundColor(index == this.selectGroupIndex ? 0xCCCCCC : Color.Transparent).padding({ left: 10 }).borderRadius(15).onClick(() => {// 导航列表选中isClickScroll=true,防止与分区列表滚动过程中带动导航列表状态变化this.isClickScroll = truethis.selectGroupIndex = index// 通过导航选中selectGroupIndex与Scroller控制分区列表滚动到对应位置this.categoryScroller.scrollToIndex(index + 2, true, ScrollAlign.START)})}}, (item: string) => item)}.listDirection(Axis.Horizontal).backgroundColor(Color.Transparent).width('100%')}
}

http://www.ppmy.cn/devtools/146352.html

相关文章

对安全的认知

上班摸鱼&#xff0c;随性写的&#xff0c;原来对安全的看法真的很窄&#xff0c;就觉得网络安全&#xff0c;无非是攻防和研究&#xff0c;就相当于觉得数学是代数和几何&#xff0c;确实是无知和片面的&#xff0c;甲方和乙方&#xff0c;对于安全的定义也是不一样的&#xf…

C++通讯录管理系统

网上看到的一个小需求&#xff0c;练练手 代码如下&#xff1a; #include <iostream> #include <string> #include <vector>//联系人 class Contact { public:Contact(const std::string& _name "无名氏", const std::string& _phoneNu…

【Linux】更换 yum 源

yum 命令是 Linux 系统中的一个包管理工具&#xff0c;主要用于安装、更新和删除软件包&#xff0c;并且能够自动处理软件包之间的依赖关系。在 Linux 系统中&#xff0c;默认使用的 yum 源通常是国外的&#xff0c;比如 CentOS 系统会使用 http://mirrorlist.centos.org/。这导…

仓颉语言实战——1. 类型

仓颉语言实战——1. 类型 仓颉语言&#xff08;Cangjie Language&#xff09;是一个现代化的、简洁而强大的编程语言&#xff0c;它的类型系统为高效开发提供了极大的支持。本篇文章将围绕仓颉语言中的类型系统展开&#xff0c;结合实战代码&#xff0c;帮助开发者快速掌握这一…

Pytorch | 利用DTA针对CIFAR10上的ResNet分类器进行对抗攻击

Pytorch | 利用DTA针对CIFAR10上的ResNet分类器进行对抗攻击 CIFAR数据集DTA介绍算法流程 DTA代码实现DTA算法实现攻击效果 代码汇总dta.pytrain.pyadvtest.py 之前已经针对CIFAR10训练了多种分类器&#xff1a; Pytorch | 从零构建AlexNet对CIFAR10进行分类 Pytorch | 从零构建…

EMI辐射骚扰测试(RE测试)

辐射骚扰测试是在微波暗室中进行的&#xff1a; 测试时候被测设备放在转台上进行360旋转&#xff1a; 接收天线从1---4米之间上升下降&#xff0c;用来测试出被测物的最大骚扰值&#xff1a; 辐射骚扰值通过测试线缆传送到接收机上去&#xff1a; EMI辐射预测试&#xff1a; 用…

优化程序中的数据:从代数到向量解

前言 在前文笔者简单介绍了把数据迭代抽象为线性代数&#xff0c;并介绍了空间体、维度等概念。 数据复用 数据复用是一种提高程序执行效率与数据局部性的方法&#xff0c;分为自复用与组复用&#xff0c; 自复用&#xff1a;如果多个迭代访问同一个内存位置&#xff0c;那…

洛谷 P1725:琪露诺 ← 单调队列+DP

【题目来源】https://www.luogu.com.cn/problem/P1725【题目描述】 在幻想乡&#xff0c;琪露诺是以笨蛋闻名的冰之妖精。 某一天&#xff0c;琪露诺又在玩速冻青蛙&#xff0c;就是用冰把青蛙瞬间冻起来。但是这只青蛙比以往的要聪明许多&#xff0c;在琪露诺来之前就已经跑到…