HarmonyOS 鸿蒙Next tabBar和@BuilderParam搭配使用,tabBar无效,代码如下

HarmonyOS 鸿蒙Next tabBar和@BuilderParam搭配使用,tabBar无效,代码如下

问题:使用tabBar时,通过@BuilderParam来引入自定义@Builder,页面布局无效,tabBar显示空白,

请问:这种问题如何解决,在使用tabBar属性的前提下~

主页Index代码(两个文件都是在同级目录下):

import { MainPage } from './MainPage'

@Entry
@Component
struct Index {
  @Provide currentIndex: number = 0 // tabs切换时,对应的下标
  
  [@Builder](/user/Builder) CommunityTabs($$ : {title: string, noSelected: ResourceStr, isSelected: ResourceStr, index: number}) {
    Column() {
      Image(this.currentIndex === $$.index ? $$.isSelected : $$.noSelected).width(22)
      Text($$.title).fontSize(14).fontColor(Color.Black)
    }.width(100).height('100%')
  }

  build() {
    Column() {
      MainPage({ CommunityTabs: this.CommunityTabs })
    }.width('100%').height('100%')
  }
}

自定义MainPage页面代码:

@Component
export struct MainPage {
  @Consume currentIndex: number;
  [@BuilderParam](/user/BuilderParam) CommunityTabs: ({title: string, noSelected: ResourceStr, isSelected: ResourceStr, index: number}) => void

  build() {
    Tabs({ barPosition: BarPosition.Start }) {
      TabContent() {
        Text('123').backgroundColor('#c0c0c0')
      }.tabBar(this.CommunityTabs({title:'社区一', noSelected:$r('app.media.icon'), isSelected:$r('app.media.icon'), index:0}))

      TabContent() {
        Text('123')
      }.tabBar(this.CommunityTabs({title:'社区二', noSelected:$r('app.media.icon'), isSelected:$r('app.media.icon'), index:1}))

      TabContent() {
        Text('123').backgroundColor('#c0c0c0')
      }.tabBar(this.CommunityTabs({title:'社区三', noSelected:$r('app.media.icon'), isSelected:$r('app.media.icon'), index:2}))
    }
    .barMode(BarMode.Fixed)
    .width('100%').height('100%')
    .onChange((value) => {
      this.currentIndex = value
    })
  }
}

更多关于HarmonyOS 鸿蒙Next tabBar和@BuilderParam搭配使用,tabBar无效,代码如下的实战教程也可以访问 https://www.itying.com/category-93-b0.html

10 回复

你的想法是,把CommunityTabs这个自定义build拿到一个单独的文件,把所有的build都放在一个文件中。

那我重新改造一下:

我定义:

CommunityTabsView.ets:存放所有的build文件。全局:
@Builder export function CommunityTabsView($$: {
  title: string,
  noSelected: ResourceStr,
  isSelected: ResourceStr,
  index: number
}) {
  Column() {
    Image(this.currentIndex === $$.index ? $$.isSelected : $$.noSelected).width(22)
    Text($$.title).fontSize(14).fontColor(Color.Black)
  }.width(100).height('100%')
}

自定义布局存放在:MainPage.ets:

import { CommunityTabsView } from './CommunityTabsView';

@Component
export default struct MainPage {

  @Consume currentIndex: number;

  private tabBarData: CommunityTabsModel[] = [
    { noSelected: $r('app.media.ic_personal_normal'), isSelected: $r('app.media.ic_personal_focus'), title: '社区一', index: 0 },
    { noSelected: $r('app.media.ic_home_normal'), isSelected: $r('app.media.ic_home_focus'), title: '社区二', index: 1 },
    { noSelected: $r('app.media.ic_cart_normal'), isSelected: $r('app.media.ic_cart_focus'), title: '社区三', index: 2 }
  ]

  build() {
    Column(){
      Tabs({ barPosition: BarPosition.Start }) {
        ForEach(this.tabBarData,(item:CommunityTabsModel)=>{
          TabContent() {
            Text('123').backgroundColor('#c0c0c0')
          }.tabBar(CommunityTabsView({ title: item.title,noSelected: item.noSelected,isSelected: item.isSelected,index: item.index }))
        },item => JSON.stringify(item))
      }
      .barMode(BarMode.Fixed)
      .width('100%').height('100%')
      .onChange((value) =>{
        this.currentIndex = value
      })
    }
  }
}

class CommunityTabsModel {
  noSelected:string | Resource
  isSelected:string | Resource
  index: number
  title: string
}

调用:

import MainPage from './MainPage';

@Entry
@Component
struct Page23 {
  @Provide currentIndex: number = 0 // tabs切换时,对应的下标

  build() {
    Column() {
      MainPage()
    }.width('100%').height('100%')
  }
}

这里就完美解决了。

更多关于HarmonyOS 鸿蒙Next tabBar和@BuilderParam搭配使用,tabBar无效,代码如下的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


太酷啦!就是这个意思,谢谢~

@BuilderParam这个错误暂时就不管它啦!

但是这个只能在API9这样写。API9以后就不能这样写了。

哪里不能这样写!API9以后@Builder就不能使用export导出了吗,

这个单独传递,不使用到tabBar是没有问题的,证明传值没有问题。如果一定要这样封装可以改造一下:

【代码】

import MainPage, { CommunityTabs } from './MainPage'

@Component
struct Page23 {
  @Provide currentIndex: number = 0 // tabs切换时,对应的下标
  build() {
    Column() {
      MainPage({ CommunityTabs: CommunityTabs })
    }.width('100%').height('100%')
  }
}

使用的还是不变,只是把@Builder提到全局:

@Component
export default struct MainPage {
  @Consume currentIndex: number;
  @BuilderParam CommunityTabs: (props :{title: string, noSelected: ResourceStr, isSelected: ResourceStr, index: number}) => void

  build() {
    Tabs({ barPosition: BarPosition.Start }) {
      TabContent() {
        Text('123').backgroundColor('#c0c0c0')
      }.tabBar(this.CommunityTabs({title:'社区一', noSelected:$r('app.media.icon'), isSelected:$r('app.media.icon'), index:0}))

      TabContent() {
        Text('123')
      }.tabBar(this.CommunityTabs({title:'社区二', noSelected:$r('app.media.icon'), isSelected:$r('app.media.icon'), index:1}))

      TabContent() {
        Text('123').backgroundColor('#c0c0c0')
      }.tabBar(this.CommunityTabs({title:'社区三', noSelected:$r('app.media.icon'), isSelected:$r('app.media.icon'), index:2}))
    }
    .barMode(BarMode.Fixed)
    .width('100%').height('100%')
    .onChange((value) => {
      this.currentIndex = value
    })
  }
}

[@Builder](/user/Builder)
export function CommunityTabs(props: {
  title: string,
  noSelected: ResourceStr,
  isSelected: ResourceStr,
  index: number
}) {
  Column() {
    Image(this.currentIndex === props.index ? props.isSelected : props.noSelected).width(22)
    Text(props.title).fontSize(14).fontColor(Color.Black)
  }.width(100).height('100%')
}

老哥,你这个没毛病,感谢你的解答!

我的想法是,把CommunityTabs这个自定义build拿到一个单独的文件,把所有的build都放在一个文件中,这样使用的话就会导致tabbar无效啦,

目前不知道什么原因导致的无效,我到API10验证,发现@BuilderParam不支持传递这样的参数。去掉所有参数那样写,一样跟API9一样。估计是Tab的一个bug。因为使用起来没有问题,就是用到tabBar就有问题。

好的好的,谢谢杰克!
这个俺已经提单啦!反反复复到现在也没解决!

代码都放在一个ets文件中就好使? 不是很理解是什么原因导致的,有没有解救办法

@Entry
@Component
struct Index {
  @Provide currentIndex: number = 0 // tabs切换时,对应的下标

  @Builder CommunityTabs($$: {
    title: string,
    noSelected: ResourceStr,
    isSelected: ResourceStr,
    index: number
  }) {
    Column() {
      Image(this.currentIndex === $$.index ? $$.isSelected : $$.noSelected).width(22)
      Text($$.title).fontSize(14).fontColor(Color.Black)
    }.width(100).height('100%')
  }

  build() {
    Column() {
      MainPage({ CommunityTabs: this.CommunityTabs })
    }.width('100%').height('100%')
  }
}

@Component
export struct MainPage {
  @Consume currentIndex: number;
  @BuilderParam CommunityTabs: ($$: {
    title: string,
    noSelected: ResourceStr,
    isSelected: ResourceStr,
    index: number
  }) => void

  build() {
    Tabs({ barPosition: BarPosition.Start }) {
      TabContent() {
        Text('123').width('100%').height('100%').backgroundColor('#c0c0c0').border({ width: 5, color: Color.Orange })
      }.tabBar(this.CommunityTabs({ title: '社区一', noSelected: $r('app.media.icon'), isSelected: $r('app.media.icon'), index: 0 }))

      TabContent() {
        Text('123')
      }.tabBar(this.CommunityTabs({ title: '社区二', noSelected: $r('app.media.icon'), isSelected: $r('app.media.icon'), index: 1 }))

      TabContent() {
        Text('123').backgroundColor('#c0c0c0')
      }.tabBar(this.CommunityTabs({ title: '社区三', noSelected: $r('app.media.icon'), isSelected: $r('app.media.icon'), index: 2 }))
    }
    .barMode(BarMode.Fixed)
    .width('100%').height('100%')
    .onChange((value) => {
      this.currentIndex = value
    })
  }
}

在HarmonyOS中,@BuilderParam用于传递一个构建器函数,而tabBar是用于底部导航栏的组件。根据你描述的代码问题,可能是由于@BuilderParam的使用方式或作用域导致tabBar无法正常渲染。

确保以下几点:

  1. @BuilderParam传递的构建器函数在正确的组件中定义。
  2. tabBar的父组件结构正确,且没有其他布局或样式冲突。
  3. @BuilderParam的作用域和生命周期管理正确,确保在tabBar渲染时构建器函数已经准备好。

检查代码中是否有以下常见问题:

  • @BuilderParam传递的构建器函数是否在正确的组件中定义。
  • tabBar是否在正确的父组件中渲染。
  • 是否有其他布局或样式冲突导致tabBar无法正常显示。

如果代码逻辑正确,可以尝试将@BuilderParamtabBar的使用拆分为更小的组件进行调试,以确定问题所在。

回到顶部