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%')}
}