“答开发者问”之HarmonyOS鸿蒙Next技术问题解析 第11期
“答开发者问”之HarmonyOS鸿蒙Next技术问题解析 第11期 向所有参与社区互助的开发者致以最诚挚的感谢!
特别感谢本期优质答复贡献者:@冉冉同学、@灯下芯、@todayisall
社区的蓬勃发展,离不开每一位积极参与者的贡献。本期“答开发者问”栏目,精选自广大热心开发者针对提问帖所贡献的众多优质答复之中。它们不仅是智慧与经验的璀璨结晶,更是“众人拾柴火焰高”这一真理的生动体现。
在此,我们由衷地感谢每一位热心参与、乐于分享的开发者,是你们的热情与智慧,让这个社区充满了生机与活力,每一次的解答都是对技术探索精神的最好诠释。同时,我们也诚挚邀请更多的开发者加入到这场智慧碰撞的盛宴中来。无论是抛出难题寻求解答,还是慷慨解囊分享经验,您的每一份参与都将为鸿蒙开发者社区注入新的活力,推动我们共同前行,在技术的海洋中扬帆远航。
本期问题如下:
- 如何实现多主题下正常模式和深色模式适配?
- 局部@Builder传参未生效问题?
- 如何在二维码的中间加个头像?
- list怎么更新单个item的ui?
- 当前HarmonyOS支持画中画和悬浮窗吗?
答开发者问系列汇总:
往期问题回顾:
“答开发者问”之HarmonyOS技术问题解析 第1期-华为开发者问答 | 华为开发者联盟 (huawei.com)
“答开发者问”之HarmonyOS技术问题解析 第2期-华为开发者问答 | 华为开发者联盟 (huawei.com)
“答开发者问”之HarmonyOS技术问题解析 第3期-华为开发者问答 | 华为开发者联盟 (huawei.com)
“答开发者问”之HarmonyOS技术问题解析 第4期-华为开发者问答 | 华为开发者联盟 (huawei.com)
“答开发者问”之HarmonyOS技术问题解析 第5期-华为开发者问答 | 华为开发者联盟 (huawei.com)
“答开发者问”之HarmonyOS技术问题解析 第6期-华为开发者问答 | 华为开发者联盟 (huawei.com)
“答开发者问”之HarmonyOS技术问题解析 第7期-华为开发者问答 | 华为开发者联盟 (huawei.com)
“答开发者问”之HarmonyOS技术问题解析 第8期-华为开发者问答 | 华为开发者联盟 (huawei.com)
“答开发者问”之HarmonyOS技术问题解析 第9期-华为开发者问答 | 华为开发者联盟 (huawei.com)
“答开发者问”之HarmonyOS技术问题解析 第10期-华为开发者问答 | 华为开发者联盟 (huawei.com)
注意:
更多关于“答开发者问”之HarmonyOS鸿蒙Next技术问题解析 第11期的实战教程也可以访问 https://www.itying.com/category-93-b0.html
问题五:当前HarmonyOS支持画中画和悬浮窗吗?
HarmonyOS当前支持画中画和悬浮窗吗?
解决方案:
关于悬浮窗模式:
- 需要申请且目前只有2in1设备才能申请。
- 需要通过应用市场申请ACL权限ohos.permission.SYSTEM_FLOAT_WINDOW。
- 需要在配置文件中添加权限说明,从而允许应用使用悬浮窗的能力。
使用ACL的签名配置指导:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/ide-signing-V14#section9786111152213。
目前只推荐画中画模式,开发指南:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V14/pipwindow-overview-V14?catalogVersion=V14
原链接:
更多关于“答开发者问”之HarmonyOS鸿蒙Next技术问题解析 第11期的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
问题四:list怎么更新单个item的ui?
问题描述:
@Observed
class TopicBean {
public count: number = 0;
constructor(count: number) {
this.count = count;
}
}
@Component
struct ObjectLinkChild {
@ObjectLink testNum: TopicBean;
build() {
Text(`ObjectLinkChild testNum ${this.testNum.count}`)
.onClick(() => {
this.testNum.count = 40;
})
}
}
@Entry
@Component
struct ParentTest {
@State topics: Array<TopicBean> = new Array()
aboutToAppear(): void {
this.topics.push(new TopicBean(10))
}
build() {
Column() {
Text(`Parent testNum ${this.topics[0].count}`)
.onClick(() => {
this.topics[0].count += 1;
})
ObjectLinkChild({ testNum: this.topics[0] })
}
}
}
建议使用V2状态管理,V2中直接topics[0].count = 6即可。
原链接:
list怎么更新单个item的ui-华为开发者问答 | 华为开发者联盟 (huawei.com)
问题三:如何在二维码的中间加个头像?
问题描述: 如果要像微信那样在二维码的中间加个头像应该怎么做,是否有对应API?
解决方案: 可以通过stack布局,将Image组件放在QRCode组件上实现,通过设置image合适大小,不会影响QRCode识别,示例代码如下:
@Entry
@Component
struct QRCodeTest {
private value: string = 'hello world';
build() {
Stack() {
QRCode(this.value)
.width(200)
.height(200)
Image($r('app.media.app_icon'))
.height(50)
.width(50)
}
.height('100%')
.width('100%')
}
}
原链接: 如果要在二维码的中间加个头像(图片)怎么做-华为开发者问答 | 华为开发者联盟 (huawei.com)
问题二:局部@Builder传参未生效问题?
问题描述:
demo代码如下:
// xxx.ets
@Entry
@Component
struct TabsExample {
@State fontColor: string = '#182431'
@State selectedFontColor: string = '#007DFF'
@State currentIndex: number = 0
@State selectedIndex: number = 0
private controller: TabsController = new TabsController()
@State num1:number=9
@State num2:number=59
@State num3:number=109
[@Builder](/user/Builder) tabBuilder(index: number, name: string,num:number) {
Column() {
Badge({
count:num,
style: { fontSize: 10, badgeSize: 1 },
position: { x: 10, y: -10 },
}) {
Text(name)
.fontColor(this.selectedIndex === index ? this.selectedFontColor : this.fontColor)
.fontSize(16)
.fontWeight(this.selectedIndex === index ? 500 : 400)
.lineHeight(22)
}
Divider()
.strokeWidth(2)
.color('#007DFF')
.opacity(this.selectedIndex === index ? 1 : 0)
}.width('100%')
}
[@Builder](/user/Builder) TabsBuilder(){
Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
TabContent() {
Column().width('100%').height('100%').backgroundColor('#00CB87')
}.tabBar(this.tabBuilder(0, 'green',this.num1))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#007DFF')
}.tabBar(this.tabBuilder(1, 'blue',this.num2))
TabContent() {
Column().width('100%').height('100%').backgroundColor('#FFBF00')
}.tabBar(this.tabBuilder(2, 'yellow',this.num3))
}
.vertical(false)
.barMode(BarMode.Fixed)
.barWidth(360)
.barHeight(56)
.animationDuration(400)
.onChange((index: number) => {
// currentIndex控制TabContent显示页签
this.currentIndex = index
})
.onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => {
if (index === targetIndex) {
return
}
// selectedIndex控制自定义TabBar内Image和Text颜色切换
this.selectedIndex = targetIndex
})
.width(360)
.height(296)
.margin({ top: 52 })
.backgroundColor('#F1F3F5')
}
build() {
Column() {
this.TabsBuilder()
}.width('100%')
}
}
当前问题是num1、num2、num3这三个参数初始时通过直接赋值的方式的话能在Badge里面显示,但是变化后重新获取到的数据不会刷新UI显示。
解决方案:
interface temp {
index: number,
name: string,
num: number
}
@Entry
@Component
struct BuilderTest {
// xxx.ets
@State fontColor: string = '#182431'
@State selectedFontColor: string = '#007DFF'
@State currentIndex: number = 0
@State selectedIndex: number = 0
private controller: TabsController = new TabsController()
@State num1: number = 9
@State num2: number = 59
@State num3: number = 69
[@Builder](/user/Builder)
tabBuilder(temp: temp) {
Column() {
Badge({
count: temp.num,
style: { fontSize: 10, badgeSize: 1 },
position: { x: 10, y: -10 },
}) {
Text(temp.name)
.fontColor(this.selectedIndex === temp.index ? this.selectedFontColor : this.fontColor)
.fontSize(16)
.fontWeight(this.selectedIndex === temp.index ? 500 : 400)
.lineHeight(22)
}
Divider()
.strokeWidth(2)
.color('#007DFF')
.opacity(this.selectedIndex === temp.index ? 1 : 0)
}.width('100%')
}
[@Builder](/user/Builder)
TabsBuilder() {
Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) {
TabContent() {
Column() {
Button("控制blue数字").onClick(() => {
this.num2++
})
}.width('100%').height('100%').backgroundColor('#00CB87')
}.tabBar(this.tabBuilder({
index: 0,
name: 'green',
num: this.num1
}))
TabContent() {
Column() {
Button("控制yellow数字").onClick(() => {
this.num3++
})
}.width('100%').height('100%').backgroundColor('#007DFF')
}.tabBar(this.tabBuilder({
index: 1,
name: 'blue',
num: this.num2
}))
TabContent() {
Column() {
Button("控制green数字").onClick(() => {
this.num1++
})
}.width('100%').height('100%').backgroundColor('#FFBF00')
}.tabBar(this.tabBuilder({
index: 2,
name: 'yellow',
num: this.num3
}))
}
.vertical(false)
.barMode(BarMode.Fixed)
.barWidth(360)
.barHeight(56)
.animationDuration(400)
.onChange((index: number) => {
// currentIndex控制TabContent显示页签
this.currentIndex = index
})
.onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => {
if (index === targetIndex) {
return
}
// selectedIndex控制自定义TabBar内Image和Text颜色切换
this.selectedIndex = targetIndex
})
.width(360)
.height(296)
.margin({ top: 52 })
.backgroundColor('#F1F3F5')
}
build() {
Column() {
this.TabsBuilder()
}.width('100%')
}
}
原链接:
[急急急!!! 局部@Builder传参问题-华为开发者问答 | 华为开发者联盟 (huawei.com)](https://developer.huawei.com/consumer/cn/forum/topicview?tid=0204167415686544462&fid=0109140870620153026)
问题一:如何实现多主题下正常模式和深色模式适配?
问题描述:
在适配多主题且每个主题都需要适配正常模式和深色模式,颜色需要怎么处理?比如一个背景颜色颜色要使用主题色 A主题 正常:#84BD00 深色:#FF5F00,另一个使用B主题正常:#00D7FF 深色:#FF0082。
解决方案:
可以抽出所有主题中公共的颜色,正常模式颜色配置在base>element>color.json中
{
"name": "theme_color",
"value": "#84BD00"
},
{
"name": "themeSec_color",
"value": "#00D7FF"
}
深色模式颜色配置在dark>element>color.json中
{
"name": "theme_color",
"value": "#FF5F00"
},
{
"name": "themeSec_color",
"value": "#FF0082"
}
采用多主题动态设置的方式来实现目标,参考demo:
import { CustomColors, CustomTheme } from '@kit.ArkUI'
class AppColors implements CustomColors {
fontPrimary: ResourceColor = $r('app.color.theme_color')
backgroundEmphasize: ResourceColor = $r('app.color.theme_color')
}
class AppColorsSec implements CustomColors {
fontPrimary: ResourceColor = $r('app.color.themeSec_color')
backgroundEmphasize: ResourceColor = $r('app.color.themeSec_color')
}
class AppTheme implements CustomTheme {
public colors: AppColors = new AppColors()
}
class AppThemeSec implements CustomTheme {
public colors: AppColors = new AppColorsSec()
}
@Entry
@Component
struct DisplayThemePage {
@State customTheme: CustomTheme = new AppTheme()
@State message: string = '设置应用局部页面自定义主题风格'
count = 0;
build() {
WithTheme({ theme: this.customTheme }) {
Row() {
Column() {
Text('WithTheme')
.fontSize(30)
.margin({ bottom: 10 })
Text(this.message)
.margin({ bottom: 10 })
Button('change theme').onClick(() => {
this.count++;
if (this.count > 1) {
this.count = 0;
}
switch (this.count) {
case 0:
this.customTheme = new AppTheme();
break;
case 1:
this.customTheme = new AppThemeSec();
break;
}
})
}
.width('100%')
}
.height('100%')
.width('100%')
}
}
}
原链接:
在“答开发者问”之HarmonyOS鸿蒙Next技术问题解析第11期中,主要聚焦于鸿蒙Next的核心技术更新与开发者常见问题。本期重点解析了分布式任务调度、设备虚拟化、以及跨设备协同等关键技术,帮助开发者更好地理解和应用鸿蒙Next的新特性。同时,针对开发者在实际开发过程中遇到的性能优化、API调用等问题,提供了详细的解决方案和最佳实践建议,助力开发者提升应用开发效率与用户体验。