HarmonyOS 鸿蒙Next 【bug反馈】Grid与Foreach的组合无法追踪多维数组的数据变动,无法改变UI

HarmonyOS 鸿蒙Next 【bug反馈】Grid与Foreach的组合无法追踪多维数组的数据变动,无法改变UI Grid和Foreach的组合可以自动跟踪一维数组的变量,但是二维数组无法根据数组的变化改写UI界面。

Foreach一次或者两次都不行。

DEV版本: DevEco Studio 3.1 Beta2 Build #DS-223.8617.56.36.310400, built on April 7, 2023 Runtime version: 17.0.5+1-b653.25 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 11 10.0 GC: G1 Young Generation, G1 Old Generation Memory: 1536M Cores: 8 Registry:     external.system.auto.import.disabled=true


更多关于HarmonyOS 鸿蒙Next 【bug反馈】Grid与Foreach的组合无法追踪多维数组的数据变动,无法改变UI的实战教程也可以访问 https://www.itying.com/category-93-b0.html

10 回复
大概找到解决方案了,数组的[@state](/user/state)重渲染需要直接在一维层面对所有的属性进行赋值、重写,不能单独对组内部的某一个具体属性赋值。

举例:

```[@state](/user/state) arraylist:Array< Array<number>>=[[0,0,0,0],[1,1,1,1],[2,2,2,2]]

以上为有效操作,可以触发UI刷新

arraylist[1][1]=3
arraylist[1][2]=3
arraylist[1][3]=3

以上为无效操作,无法触发UI刷新

更多关于HarmonyOS 鸿蒙Next 【bug反馈】Grid与Foreach的组合无法追踪多维数组的数据变动,无法改变UI的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


感谢您的反馈,如后期有疑问可以随时发帖,感谢您的支持。

开发者您好,能提供下复现代码吗?

可以的,

基本信息

  • 姓名: 张三
  • 年龄: 28
  • 职位: 软件工程师

技能

  • Python
  • Java
  • C++

项目经验

  • 项目一
    • 描述: 使用Python开发了一个自动化测试框架
    • 责任: 设计和实现测试用例,优化测试流程
  • 项目二
    • 描述: 参与开发一个电商网站
    • 责任: 实现用户登录功能,优化页面加载速度

import router from ‘@ohos.router’; import DefaultColor from ‘…/servises/SeverFor2048/DefaultColor’ import SecondColor from ‘…/servises/SeverFor2048/SecondColor’ import promptAction from ‘@ohos.promptAction’;
PersistentStorage.PersistProp(‘maxScore’, 2);

@Entry @Component struct Game2048 {
@State info: string = ‘游戏说明:’ +
‘滑动屏幕移动数字,合并相同数字,向着更大的数字冲刺吧!’
@State maxScore: number = AppStorage.Get(‘maxScore’)
@State nowScore: number = 2
@State numberArray: Array<Array<number>> = [[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]]

aboutToAppear() {     
    for (var k = 0;k < 3; k++) {       
        let random = Math.floor(Math.random() * (16 - k))        
        for (var i = 0;i < 4; i++) { //查询当前0位数量         
            for (var l = 0;l < 4; l++) {           
                if (this.numberArray[i][l] == 0) {             
                    if (random == 0) {                 
                        this.numberArray[i][l] = 2             
                        random--                       
                    } else {                             
                        random--                         
                    }                                   
                }                                       
            }                                           
        }                                               
    }                                                 
}                                                    

build() {     
    Column() {       
        Row() {         
            Button('返回主页')           
                .fontSize(30)           
                .onClick(() => {             
                    router.replaceUrl({               
                        url: "pages/Index"             
                    })                           
                })                         
        }                              

        Row() { //展示分数         
            Column() {           
                Text('历史最高分:' + this.maxScore)             
                    .fontSize(25)           
                Text('本局分数:' + this.nowScore)             
                    .fontSize(25)           
            }                                  
        }                                      
            .width('100%')           
            .height('60vp')          

        Column() { //存放游戏主体         
            Grid() {           
                ForEach(this.numberArray,(X) => {             
                    ForEach(this.numberArray,(Y)=>{               
                        GridItem() {               
                            Text(Y.toString())               
                        }               
                            .width('55vp')               
                            .height('55vp')               
                            .backgroundColor(color.browm)             
                    },)           
                },)             
            }             
                .columnsTemplate('1fr 1fr 1fr 1fr')             
                .rowsTemplate('1fr 1fr 1fr 1fr')           
        }           
            .gesture(             
                GestureGroup(GestureMode.Exclusive,               
                    PanGesture({ fingers: 1,                 
                        direction: PanDirection.Right })               
                        .onActionEnd(() => {                 
                            for (var i = 0;i <4; i++) {                    
                                for (var l = 0;l <4; l++) {                    
                                    this.numberArray-=10                  
                                }                      
                            }                      
                            this.maxNumber()                    
                        })               
                    ,               
                    PanGesture({ fingers: 1,                 
                        direction: PanDirection.Left })               
                        .onActionEnd(() => {                 
                            for (var i = 0;i <4; i++) {                    
                                for (var l = 0;l <4; l++) {                    
                                    this.numberArray+=10                  
                                }                      
                            }                      
                            this.maxNumber()                    
                        })               
                    ,               
                    PanGesture({ fingers: 1,                 
                        direction: PanDirection.Up })               
                        .onActionEnd(() => {                 
                            for (var i = 0;i <4; i++) {                    
                                for (var l = 0;l <4; l++) {                    
                                    this.numberArray-=5                  
                                }                      
                            }                      
                            this.maxNumber()                    
                        })               
                    ,               
                    PanGesture({ fingers: 1,                 
                        direction: PanDirection.Down })               
                        .onActionEnd(() => {                 
                            for (var i = 0;i <4; i++) {                    
                                for (var l = 0;l <4; l++) {                    
                                    this.numberArray+=5                  
                                }                      
                            }                      
                            this.maxNumber()                    
                        })               
                )             
            )             
                .width('300vp')           
                .height('300vp')           
                .backgroundColor($r('app.color.2048BigSquare'))           

        Text(this.info)             
            .fontSize(30)            

        Blank()           
        Button('重新开始')             
            .fontSize(30)             
            .onClick(() => {               
                router.replaceUrl({                 
                    url: "pages/2048"               
                })                             
            })     
    }     
        .height('100%')     
        .width('100%')     
        .backgroundColor($r('app.color.2048Background'))    
}      

maxNumber() { //寻找最大值并修改数据。     
    for (var i = 0;i < 4; i++) {       
        for (var l = 0;l < 4; l++) {         
            if (this.numberArray[i][l] > this.nowScore) {           
                this.nowScore = this.numberArray[i][l]           
                if (this.nowScore > this.maxScore) {             
                    this.maxScore = this.nowScore             
                    AppStorage.SetOrCreate('maxScore', this.maxScore)           
                }             
            }           
        }         
    }       
}   

}

滑动屏幕,可以从总分上看到多维数组中的值其实是正常变动的,但是在前端看不到与多维数组绑定的数值被刷新。

改完数组,push一下数组,就arr.push(),这样应该可以,实在不行,你还可以JSON.stringify(JSON.parse(arr))

这个办法试了下没有用。

在HarmonyOS鸿蒙系统中,关于Grid与Foreach组合无法追踪多维数组数据变动并更新UI的问题,这通常是由于数据绑定机制未能正确响应数组内部元素的变化。

鸿蒙系统的UI框架依赖于数据绑定来自动更新界面,但当使用Grid与Foreach组件遍历多维数组时,如果数组内部的结构(如子数组的元素)发生变化,而外层数组引用未变,系统可能无法检测到这些细微的数据变动。

解决此类问题的一种方法是确保当多维数组内部数据变化时,能够触发外层数组或相关数据的更新通知。例如,可以通过创建一个新的数组对象来替换旧数组,即使内容相同,只要引用改变,系统就能检测到数据变动并更新UI。

另一种方法是检查数据模型的实现,确保所有相关的属性都实现了INotifyPropertyChanged接口(如果鸿蒙系统支持类似机制)或使用了可观察集合,以便在数据变化时发出通知。

如果上述方法仍无法解决问题,可能是由于鸿蒙系统当前版本的一个限制或bug。此时,建议直接联系鸿蒙系统的官方技术支持,以获取更专业的帮助和解决方案。

如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html

回到顶部