【HarmonyOS Next开发】Tabs使用封装

2024-12-24 23:05:36
7次阅读
0个评论

 背景

在写Tabs时,会使用很多个TabContent来实现不同页面的展示内容,但是如果TabContent数量很多时,会导致Tabs代码量大而且很臃肿,因此想着尝试去封装Tabs的使用,可以让界面整洁和对内容界面的解耦。

主要依托于wrapBuilder:封装全局@Builder的方法使用。需要注意从API 11 才开始支持使用

代码结构

cke_7167.png

Index.ets

import { TabbarItem, TabbarItemList } from '../Models/TabbarItem';

@Entry
@Component
struct Index {
  // tab选择索引
  @State selectIndex: number = 0;
  // 内容
  controller: TabsController = new TabsController()
  // tab集合
  @State items: TabbarItem[] = TabbarItemList;

  build() {
    Tabs({ controller: this.controller, index: this.selectIndex }) {
      ForEach(this.items, (item: TabbarItem, index: number) => {
        TabContent() {
          //点击页签显示的内容
          item.builder.builder()
        }
        .tabBar(this.tabarBuilder(item, index)) //TabContent的样式和内容
      })
    }.onChange((index: number) => {
      this.selectIndex = index;
    })
    .barPosition(BarPosition.End);
  }

  @Builder
  tabarBuilder(item: TabbarItem, index: number) {
    Column() {
      Image(this.selectIndex == index ? item.icon_selected : item.icon_normal)
        .width(28)
        .aspectRatio(1)
        .margin({ top: 5, bottom: 1 });
      Text(item.title)
        .width('100%')
        .height(14)
        .fontSize(10)
        .fontWeight(500)
        .textAlign(TextAlign.Center)
        .margin({ bottom: 7 });
    }
  }
}

TabbarItem.ets

import { View1Builder } from '../Views/View1_Page';
import { View2Builder } from '../Views/View2_Page';
import { View3Builder } from '../Views/View3_Page';
import { View4Builder } from '../Views/View4_Page';
import { View5Builder } from '../Views/View5_Page';

class TabbarItem {
  index: number = 0;
  title: string = '';
  icon_selected: Resource = $r('app.media.app_icon');
  icon_normal: Resource = $r('app.media.app_icon');
  builder: WrappedBuilder<[]> = wrapBuilder(TabbarBuilder);

  constructor(index: number, title: string, selectedIcon: Resource, normalIcon: Resource, builder: WrappedBuilder<[]>) {
    this.index = index;
    this.title = title;
    this.icon_selected = selectedIcon;
    this.icon_normal = normalIcon;
    this.builder = builder;
  }
}

@Builder
function TabbarBuilder() {

}


// tab集合
const TabbarItemList: TabbarItem[] = [
  new TabbarItem(0, "View1", $r('app.media.app_icon'), $r('app.media.app_icon'), wrapBuilder(View1Builder)),
  new TabbarItem(1, "View2", $r('app.media.app_icon'), $r('app.media.app_icon'), wrapBuilder(View2Builder)),
  new TabbarItem(2, "View3", $r('app.media.app_icon'), $r('app.media.app_icon'), wrapBuilder(View3Builder)),
  new TabbarItem(3, "View4", $r('app.media.app_icon'), $r('app.media.app_icon'), wrapBuilder(View4Builder)),
  new TabbarItem(4, "View5", $r('app.media.app_icon'), $r('app.media.app_icon'), wrapBuilder(View5Builder)),
]


export {
  TabbarItem, TabbarItemList
}

View1_Page.ets

@Builder
export function View1Builder(){
  View1_Page();
}

@Entry
@Component
struct View1_Page {
  @State message: string = 'View1';

  build() {
    RelativeContainer() {
      Text(this.message)
        .id('View1_PageHelloWorld')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
    }
    .height('100%')
    .width('100%')
  }
}

 效果

cke_121422.png

cke_124375.png

收藏00

登录 后评论。没有帐号? 注册 一个。