BottomNavigationComponent.ets 7.43 KB
import { BottomNavi, CommonConstants } from 'wdConstant';
import { BottomNavDTO, TopNavDTO } from 'wdBean';
import { DateTimeUtils, EmitterEventId, EmitterUtils, Logger } from 'wdKit';
import { TopNavigationComponent } from './TopNavigationComponent';
import { MinePageComponent } from './MinePageComponent';
import { CompUtils } from '../../utils/CompUtils';
import PageViewModel from '../../viewmodel/PageViewModel';
import HomeChannelUtils, { AssignChannelParam } from 'wdRouter/src/main/ets/utils/HomeChannelUtils';
import { Message } from 'wdJsBridge/src/main/ets/bean/Message';

const TAG = 'BottomNavigationComponent';
let storage = LocalStorage.getShared();

/**
 * 底部页签导航栏/底导
 */
@Entry(storage)
@Component
export struct BottomNavigationComponent {
  @Provide bottomRectHeight: number = 0
  @Provide topRectHeight: number = 0
  @Provide isLayoutFullScreen: boolean = false
  @Provide isImmersive: boolean = false // 是否开启沉浸式模式 http://192.168.1.3:3300/project/3802/interface/api/189229
  @Provide isNight: boolean = false // 是否开启夜间模式
  @Provide currentBottomNavInfo: BottomNavDTO = {} as BottomNavDTO; // 当前底导信息
  @Provide currentTopNavInfo: TopNavDTO = {} as TopNavDTO; // 当前顶导信息
  @Provide barBackgroundColor: Color = Color.Transparent
  @State bottomSafeHeight: number = AppStorage.get<number>('bottomSafeHeight') || 0
  @State topSafeHeight: number = AppStorage.get<number>('topSafeHeight') || 0
  @State @Watch('onBottomNavigationDataUpdated') bottomNavList: BottomNavDTO[] = [] // 底导/顶导全部数据
  @State currentNavIndex: number = BottomNavi.NEWS; // 底导当前选中/焦点下标
  // 底导TabsController
  private navController: TabsController = new TabsController();
  readonly ASPECT_RATIO_1_1: number = 1 / 1; // 底导图片宽高比
  /**
   * Component opacity value: 1.
   */
  readonly FULL_OPACITY: number = 1;
  /**
   * Component opacity value: 0.6.
   */
  readonly SIXTY_OPACITY: number = 0.6;
  // 用于传参到顶导组件,【不用channelParam,主要是时序问题,需要先底导处理完,再延时触发顶导处理】
  @State assignChannel: AssignChannelParam = new AssignChannelParam()
  // 自动刷新触发(双击tab自动刷新)
  @State autoRefresh: number = 0

  async aboutToAppear() {
    Logger.info(TAG, `aboutToAppear currentNavIndex: ${this.currentNavIndex}`);
    let bottomNav = await PageViewModel.getBottomNavData(getContext(this))
    if (bottomNav && bottomNav.bottomNavList != null) {
      Logger.info(TAG, `aboutToAppear, bottomNav.length: ${bottomNav.bottomNavList.length}`);
      // 使用filter方法移除name为'服务'的项
      bottomNav.bottomNavList = bottomNav.bottomNavList.filter(item => item.name !== '服务');
      this.bottomNavList = bottomNav.bottomNavList
    }
    HomeChannelUtils.setBottomNavData(bottomNav)

    EmitterUtils.receiveEvent(EmitterEventId.JUMP_HOME_CHANNEL, (str?: string) => {
      Logger.debug(TAG, 'receiveEvent JUMP_HOME_CHANNEL: ' + str)
      if (str) {
        // 跳转指定频道场景,传参底导id、频道id
        let assignChannel = JSON.parse(str) as AssignChannelParam
        this.changeBottomNav(assignChannel)
      }
    })
  }

  aboutToDisappear() {
    Logger.info(TAG, `aboutToDisappear, this.currentNavIndex: ${this.currentNavIndex}`);
  }

  build() {
    Tabs({ barPosition: BarPosition.End, index: this.currentNavIndex, controller: this.navController }) {
      ForEach(this.bottomNavList, (navItem: BottomNavDTO, index: number) => {
        TabContent() {
          Column() {
            if (CompUtils.isMine(navItem)) {
              // 我的页面组件数据列表
              MinePageComponent()
            } else {
              TopNavigationComponent({
                groupId: navItem.id,
                topNavList: navItem.topNavChannelList.filter(item => item.channelId != 2073),
                _currentNavIndex: $currentNavIndex,
                navIndex: index,
                currentBottomNavName: navItem.name,
                assignChannel: this.assignChannel,
                autoRefresh: this.autoRefresh
              })
            }

          }
        }
        .tabBar(this.tabBarBuilder(navItem, index))
      });

    }
    .animationDuration(0)
    .barHeight($r('app.float.bottom_navigation_barHeight'))
    .barMode(BarMode.Fixed)
    .barBackgroundColor(this.barBackgroundColor)
    // 备注:鸿蒙目前只有修改三线导航背景方法,对于全面屏导航条手机需要设置背景色并使其扩散到导航区域
    .backgroundColor(this.barBackgroundColor)
    .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])

    // .padding({ bottom: this.bottomRectHeight + 'px', top: this.topRectHeight + 'px' }) // 此处margin具体数值在实际中应与导航条区域高度保持一致

  }

  @Builder
  tabBarBuilder(navItem: BottomNavDTO, index: number) {
    Stack({ alignContent: Alignment.Bottom }) {
      Image(this.currentNavIndex === index ? navItem.iconC : navItem.icon)
        .height(CommonConstants.FULL_PARENT)
        .padding({ bottom: 15, left: 10, right: 10, top: 2 })
        .aspectRatio(this.ASPECT_RATIO_1_1)

      Text(navItem.name)
        .margin({ bottom: $r('app.float.bottom_navigation_margin_bottom') })
        .fontWeight(this.currentNavIndex === index ? FontWeight.Bold : FontWeight.Normal)
        .textAlign(TextAlign.Center)
        .fontSize($r('app.float.font_size_10'))// .fontColor(this.currentNavIndex === index ? Color.Red : Color.Gray)
        .fontColor(this.currentNavIndex === index ? navItem.nameCColor : navItem.nameColor)
        .opacity(this.currentNavIndex === index ? this.FULL_OPACITY : this.SIXTY_OPACITY)
    }
    .height($r('app.float.bottom_navigation_barHeight'))
    .hoverEffect(HoverEffect.Highlight)
    .onClick(() => {
      if (navItem.name === '我的') {
        this.barBackgroundColor = Color.White
        this.currentBottomNavInfo = {} as BottomNavDTO
      } else {
        if (this.currentNavIndex === index) {
          // 当前tab,单击事件
          this.autoRefresh++
        } else {
          // 切换tab
          this.currentBottomNavInfo = navItem
        }
      }

      this.currentNavIndex = index;
      Logger.info(TAG, `onChange, index: ${index}`);

    })

  }

  // 底导切换函数
  onBottomNavigationIndexChange() {
    Logger.info(TAG, `onBottomNavigationIndexChange this.currentNavIndex: ${this.currentNavIndex}`);
    // 请求顶导数据(参数):
  }

  onBottomNavigationDataUpdated() {
    // Logger.info(TAG, `onBottomNavigationDataUpdated currentNavIndex: ${this.currentNavIndex},length:${this.bottomNavItemList.length}`);
    this.onBottomNavigationIndexChange()
  }

  /**
   * 底导id变化,即指定频道跳转场景
   */
  changeBottomNav(assignChannel: AssignChannelParam) {
    let index = -1
    for (let i = 0; i < this.bottomNavList.length; i++) {
      let bottomNavDTO: BottomNavDTO = this.bottomNavList[i]
      if (bottomNavDTO.id.toString() === assignChannel.bottomNavId) {
        index = i
        break
      }
    }
    if (index >= 0 && index != this.currentNavIndex) {
      // 切底导
      this.currentNavIndex = index
    }

    setTimeout(() => {
      // 底导切换后,触发顶导切换
      this.assignChannel = new AssignChannelParam()
      this.assignChannel.pageId = assignChannel.pageId
      this.assignChannel.channelId = assignChannel.channelId
      this.assignChannel.bottomNavId = assignChannel.bottomNavId
    }, 20)
  }
}