1、HarmonyOS 怎么用一個變量觀察其他很多個變量的變化?
有一個提交按鈕的顏色,需要很多個值非空才變為紅色,否則變為灰色,可不可以用一個變量統一觀察這很多個值,去判斷按鈕該顯示什么顏色,比如Button().backgroundColor(this.color),this.color的值取決于很多個輸入框的值
想將子組件與父組件的變量綁定起來,實現其中一個變量改變,對應的變量也做同步的改變,可以做如下操作:將子組件的變量需要用@Link修飾,且不能初始化將父組件的變量需要用@State修飾。傳值的時候使用$符號修飾。
import Prompt from '@system.prompt'
@Entry
@Component
struct Index {//父組件的變量需要用@State修飾@State inputUserName:string ='張三'@State inputUserPsw:string ='張三'build() {Row() {Column() {Text(this.inputUserName).fontSize(20)// 使用子組件傳值的時候用$傳遞LoginInput({hint:'請輸入賬號',inputVale:$inputUserName})LoginInput({hint:'請輸入賬號',inputVale:$inputUserPsw})}.width('100%')}.height('100%')}}
@Component
struct LoginInput {private hint: string = '請輸入賬號密碼';//子組件的變量需要用@Link修飾,且不能初始化@Link inputVale: string;build() {TextInput({placeholder:this.hint,text:this.inputVale}).onChange((value)=>{this.inputVale= value;Prompt.showToast({message:value})})}
}
2、HarmonyOS 動畫過程中UI殘留?
等長沒有異常。只有3->2出現 出現后點擊屏幕任意點 刷新消失
參考以下示例通過onChange實現切換時自定義tabBar和TabContent的聯動:
// xxx.ets
@Entry
@Component
struct TabsExample {@State fontColor: string = '#182431'@State selectedFontColor: string = '#007DFF'@State currentIndex: number = 0private controller: TabsController = new TabsController()@Builder tabBuilder(index: number, name: string) {Column() {Text(name).fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor).fontSize(16).fontWeight(this.currentIndex === index ? 500 : 400).lineHeight(22).margin({ top: 17, bottom: 7 })Divider().strokeWidth(2).color('#007DFF').opacity(this.currentIndex === index ? 1 : 0)}.width('100%')}build() {Column() {Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {TabContent() {Column().width('100%').height('100%').backgroundColor('#00CB87')}.tabBar(this.tabBuilder(0, 'green'))TabContent() {Column().width('100%').height('100%').backgroundColor('#007DFF')}.tabBar(this.tabBuilder(1, 'blue'))TabContent() {Column().width('100%').height('100%').backgroundColor('#FFBF00')}.tabBar(this.tabBuilder(2, 'yellow'))TabContent() {Column().width('100%').height('100%').backgroundColor('#E67C92')}.tabBar(this.tabBuilder(3, 'pink'))}.vertical(false).barMode(BarMode.Fixed).barWidth(360).barHeight(56).animationDuration(400).onChange((index: number) => {this.currentIndex = index}).width(360).height(296).margin({ top: 52 }).backgroundColor('#F1F3F5')}.width('100%')}
}
3、HarmonyOS Tabs 控件 底部顯示不全?
Tabs 控件 底部顯示不全 TabContent() 中的頁面,底部顯示不全
Scroll(this.scroller)的高度設百分比,和上面的相加為100%即可,參考DEMO:
@Entry
@Component
struct newPage {@State fontColor: string = '#182431'@State selectedFontColor: string = '#007DFF'@State currentIndex: number = 0private controller: TabsController = new TabsController()scroller: Scroller = new Scroller()private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]@BuildertabBuilder(index: number, name: string) {Column() {Text(name).fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor).fontSize(16).fontWeight(this.currentIndex === index ? 500 : 400).lineHeight(22).margin({ top: 17, bottom: 7 })Divider().strokeWidth(2).color('#007DFF').opacity(this.currentIndex === index ? 1 : 0)}.width('100%')}build() {Column() {Tabs({ barPosition: BarPosition.End, index: this.currentIndex, controller: this.controller }) {TabContent() {Column() {Row() {Text('首頁').align(Alignment.Center)}.justifyContent(FlexAlign.Center).height('10%') //上面的設10%.width('100%').padding({ left: 10, right: 10 }).backgroundColor(Color.Green)Scroll(this.scroller) {Column() {ForEach(this.arr, (item: number) => {Text(item.toString()).width('90%').height(150).backgroundColor(0xFFFFFF).borderRadius(15).fontSize(16).textAlign(TextAlign.Center).margin({ top: 10 })}, (item: string) => item)}.width('100%')}.height('90%') //Scroll設90%.scrollable(ScrollDirection.Vertical) // 滾動方向縱向.friction(0.6).edgeEffect(EdgeEffect.None)}}.tabBar(this.tabBuilder(0, 'green'))TabContent() {Column().width('100%').height('100%').backgroundColor('#007DFF')}.tabBar(this.tabBuilder(1, 'blue'))}.vertical(false).barMode(BarMode.Fixed).barWidth(360).barHeight(56).animationDuration(400).onChange((index: number) => {this.currentIndex = index}).width('100%').height('100%').backgroundColor('#F1F3F5')}.width('100%').height('100%')}
}
4、HarmonyOS 被@ObservedV2和@Trace標記的類及字段,使用JSON.stringify之后字段名稱都加上了“__ob_”
開頭的字段?
使用JSON.stringify序列化之后字段名稱都改變了,導致無法反序列化回來。
關于序列化后會有__ob_
前綴的問題,可以在序列前替換掉__ob_
前綴,demo如下
import { plainToClass } from "class-transformer";
@ObservedV2
class Son {@Trace age: number = 100;
}
class Father {son: Son = new Son();
}
@Entry
@Component
struct Index {father: Father = new Father();aboutToAppear(): void {let a = JSON.stringify(this.father);let b: Father = plainToClass(Father,this.father);//{"son":{"__ob_age":100}}替換成{"son":{"age":100}}console.log(JSON.stringify(convertKeysToCamelCase(this.father)))}build() {Column() {// 當點擊改變age時,Text組件會刷新Text(`${this.father.son.age}`).onClick(() => {this.father.son.age++;})}}
}// utils.ets
export function underscoreToCamelCase(underscoreString:string):string {// 捕獲__ob_替換成''return underscoreString.replace(/(__ob_)/g, (match:string, letter:string):string=> {console.log(letter)return '';});
}
export function convertKeysToCamelCase(obj:ESObject):ESObject {if (obj && typeof obj === 'object') {const newObj:ESObject = {};Object.keys(obj).forEach((key)=> {if (obj.hasOwnProperty(key)) {const newKey = underscoreToCamelCase(key);newObj[newKey] = convertKeysToCamelCase(obj[key]);}})return newObj;} else {return obj;}
}
5、HarmonyOS 文字背景局部拉伸問題?
- backgroundImageResizable設置無作用,Image設置resizable是可以的
- 如何讓同級控件寬度自適應文字寬度
獲取文本長度的方式參考文檔,讓backgroundImageSize改為文字的寬度:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-measure-V5#ZH-CN_TOPIC_0000001884917586__measuremeasuretext
實現方式demo:
import measure from '@ohos.measure'@Entry
@Component
struct IR240513200608052 {@State message: string = 'Hello World啊哈哈哈哈哈哈哈哈哈';@State textWidth: number = measure.measureText({ textContent: this.message })build() {Column() {Text(this.message).backgroundImage($r('app.media.startIcon')).backgroundImageResizable({slice: {top: 3,left: 3,bottom: 3,right: 3}}).backgroundImageSize({ width: this.textWidth })}.height('100%').width('100%')}
}