实现动态底导航并配合Tabs,Navigation组件实现动态添加子组件的能力 - HarmonyOS 鸿蒙Next

实现动态底导航并配合Tabs,Navigation组件实现动态添加子组件的能力 - HarmonyOS 鸿蒙Next 目前使用的是 Navigation 的 toolbar 能力。无法进行扩展。没有找到其他 Bar 的组件,自定义 Bar 如何实现
Tabs 组件如何实现动态添加。如无法实现动态添加将无法实现扩展动态底导航。Tabs 的子组件和 Navigation 的子组件都不是固定的。需要动态生成的。

3 回复

目前navigation的toolbar当数量过多时是显示更多按钮,只支持点击,不支持上来展示更多

动态添加请参考如下demo:

//navigation的toolbar动态添加
import { SymbolGlyphModifier } from '@kit.ArkUI';

@Entry
@Component
struct NavigationExample {
  @Provide('navPathStack') navPathStack:NavPathStack = new NavPathStack();
  @State menuItems:Array<NavigationMenuItem> = [
    {
      value:'menuItem1',
      icon:'resources/base/media/ic_public_ok.svg' // 图标资源路径
    },
    {
      value:'menuItem2',
      icon:'resources/base/media/ic_public_ok.svg', // 图标资源路径
      symbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_folder_badge_plus')).fontColor([Color.Red,Color.Green]).renderingStrategy(SymbolRenderingStrategy.MULTIPLE_COLOR),
    },
    {
      value:'menuItem3',
      symbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_lungs')),
    },
  ]

  @State toolItems:Array<ToolbarItem>= [
    {
      value:'toolItem1',
      icon:'resources/base/media/ic_public_ok.svg', // 图标资源路径
      symbolIcon:new SymbolGlyphModifier($r('sys.symbol.ohos_lungs')),
      status:ToolbarItemStatus.ACTIVE,
      activeSymbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_folder_badge_plus')).fontColor([Color.Red,Color.Green]).renderingStrategy(SymbolRenderingStrategy.MULTIPLE_COLOR),
      action:(){}
    },
    {
      value:'toolItem2',
      symbolIcon:new SymbolGlyphModifier($r('sys.symbol.ohos_star')),
      status:ToolbarItemStatus.ACTIVE,
      activeIcon: 'resources/base/media/ic_public_more.svg', // 图标资源路径
      action:(){}
    },
    {
      value:'toolItem3',
      symbolIcon:new SymbolGlyphModifier($r('sys.symbol.ohos_star')),
      status:ToolbarItemStatus.ACTIVE,
      activeSymbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_lungs')),
      action:(){}
    }
  ]

  @Builder
  myRouter(name:string,param?:Object) {
    if(name === 'NavigationMenu') {
      NavigationMenu();
    }
  }

  build() {
    Navigation(this.navPathStack) {
      Column() {
        Button('跳转').onClick(() => {
          this.navPathStack.pushPathByName('NavigationMenu', null);
        })
        Button('添加').onClick(() => {
          this.toolItems.push({
            value:'toolItem3',
            symbolIcon:new SymbolGlyphModifier($r('sys.symbol.ohos_star')),
            status:ToolbarItemStatus.ACTIVE,
            activeSymbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_lungs')),
            action:{}
          })
        })
      }
    }
    .backButtonIcon(new SymbolGlyphModifier($r('sys.symbol.ohos_wifi')))
    .titleMode(NavigationTitleMode.Mini)
    .menus(this.menuItems)
    .toolbarConfiguration(this.toolItems)
    .title('一级页面')
    .navDestination(this.myRouter)
  }
}

@Component
export struct NavigationMenu{
  @Consume('navPathStack') navPathStack:NavPathStack;
  @State menuItems:Array<NavigationMenuItem> = [
    {
      value:'menuItem1',
      icon:'resources/base/media/ic_public_ok.svg', // 图标资源路径
      action:(){}
    },
    {
      value:'menuItem2',
      symbolIcon: new SymbolGlyphModifier($r('sys.symbol.ohos_folder_badge_plus')).fontColor([Color.Red,Color.Green]).renderingStrategy(SymbolRenderingStrategy.MULTIPLE_COLOR),
      action:(){}
    },
    {
      value:'menuItem3',
      symbolIcon: new SymbolGlyphModifier($r('sys.symbol.repeat_1')),
      action:(){}
    },
  ]

  build() {
    NavDestination(){
      Row() {
        Column(){
        }
        .width('100%')
      }
      .height('100%')
    }
    .hideTitleBar(false)
    .title('NavDestination title')
    .backgroundColor($r('sys.color.ohos_id_color_titlebar_sub_bg'))
    .backButtonIcon(new SymbolGlyphModifier($r('sys.symbol.ohos_star')).fontColor([Color.Blue]))
    .menus(this.menuItems)
  }
}

//tabs组件动态添加
class CurrentIndex {
  public currentIndex: number = 0;
}

@Builder
function JhkPageMain($$: CurrentIndex) {
  pageMain({currentIndex: $$.currentIndex})
}

@Component
struct pageMain {
  @Prop @Watch('onCountUpdated') currentIndex: number;
  @State total: number = 0;
  @State txt: string = '默认显示';

  aboutToAppear(): void {
    console.log('输出:',JSON.stringify(this.currentIndex))
  }

  // @Watch 回调
  onCountUpdated(propName: string): void {
    console.log('输出:currentIndex',this.currentIndex)
    console.log('输出:total',this.total)
    if (this.total != this.currentIndex) {
      this.txt = 'pageMain组件隐藏了'
    }else{
      this.txt = 'pageMain组件重新显示了'
    }
  }

  build() {
    Column(){
      Text(this.txt)
    }
  }
}

@Builder
function JhkPageNews(index: CurrentIndex) {
  pageNews()
}

@Component
struct pageNews {
  build() {
    Column().width('100%').height('100%').backgroundColor('#ff0033cb')
  }
}

@Builder
function JhkPageMine(index: CurrentIndex) {
  pageMine()
}

@Component
struct pageMine {
  build() {
    Column().width('100%').height('100%').backgroundColor('#ffcb0018')
  }
}

@Builder
export function JhkTestTabsPage() {
  BuildPage()
}

@Component
struct BuildPage {
  @State contentBuilderList: WrappedBuilder<[CurrentIndex]>[] =
    [
      wrapBuilder(JhkPageMain),
      wrapBuilder(JhkPageNews),
      wrapBuilder(JhkPageMine),
    ];

  build() {
    Column(){
      tabsBuildPage({
        contentBuilderList: this.contentBuilderList
      })

    }
  }
}

@Component
struct tabsBuildPage {
  @State fontColor: string = '#182431'
  @State selectedFontColor: string = '#007DFF'
  @State currentIndex: CurrentIndex = new CurrentIndex()
  @State contentBuilderList: WrappedBuilder<[CurrentIndex]>[] = []
  private controller: TabsController = new TabsController()

  @Builder tabBuilder(index: number, name: string) {
    Column() {
      Text(name)
        .fontColor(this.currentIndex.currentIndex === index ? this.selectedFontColor : this.fontColor)
        .fontSize(16)
        .fontWeight(this.currentIndex.currentIndex === index ? 500 : 400)
        .lineHeight(22)
        .margin({ top: 17, bottom: 7 })
      Divider()
        .strokeWidth(2)
        .color('#007DFF')
        .opacity(this.currentIndex.currentIndex === index ? 1 : 0)
    }.width('100%')
  }

  build() {
    Column() {
      Tabs({ barPosition: BarPosition.Start, index: this.currentIndex.currentIndex, controller: this.controller }) {
        ForEach(this.contentBuilderList, (itemBuilder: WrappedBuilder<[CurrentIndex]>, index: number) => {
          TabContent() {
            itemBuilder.builder({ currentIndex: this.currentIndex.currentIndex });
          }
          .tabBar(this.tabBuilder(index, `${index}`))
        })
      }
      .vertical(false)
      .barMode(BarMode.Fixed)
      .barWidth(360)
      .barHeight(56)
      .animationDuration(400)
      .onChange((index: number) => {
        this.currentIndex.currentIndex = index
      })
      .width(360)
      .height(296)
      .margin({ top: 52 })
      .backgroundColor('#F1F3F5')
      Button('添加')
        .onClick(()=>{
          this.contentBuilderList.push(
            wrapBuilder(JhkPageMine),
          )
        })

    }.width('100%')
  }
}

@Entry
@Component
struct Page {

  build() {
    Column(){
      JhkTestTabsPage()
    }
  }
}

更多关于实现动态底导航并配合Tabs,Navigation组件实现动态添加子组件的能力 - HarmonyOS 鸿蒙Next的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


参考一下别人的https://gitee.com/harmonyos_samples/CommentReply/blob/master/features/home/src/main/ets/view/Home.ets

Navigation + 自定义的tabs,然后关于tabs的数据无非就是定义一下变量在初始化时候从后端接口获取

在HarmonyOS鸿蒙Next系统中,实现动态底导航并配合Tabs,以及利用Navigation组件动态添加子组件的能力,可以通过以下方式实现:

  1. 底导航实现:

    • 使用DirectionalLayoutStackLayout等布局容器作为底导航的基础。
    • 为每个导航项设置点击事件监听器,通过监听器控制页面跳转或视图切换。
  2. Tabs实现:

    • 利用TabControl组件实现标签页切换功能。
    • TabControl与底导航项关联,确保导航项点击时能正确切换对应的标签页。
  3. 动态添加子组件:

    • 使用AbilitySliceFragment作为子组件的容器。
    • 在需要动态添加子组件时,通过编程方式创建并添加新的AbilitySliceFragment实例到容器中。
    • 利用Navigator组件的API实现页面间的跳转和参数的传递。
  4. 注意事项:

    • 确保所有动态添加的组件都已正确注册在应用的配置文件中。
    • 处理好组件间的数据传递和状态管理,避免内存泄漏和性能问题。

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

回到顶部