鸿蒙ArkTS Tabs组件开发底部导航栏,可自适应平板和手机,相当于Android开发中的MainActivity+Fragment的底部导航栏模式。
import { BreakpointSystem, BreakpointConstants, StyleConstants, PageConstants, } from '@ohos/common'; // 通用工具 import { Chat } from '@ohos/chat'; // 子模块 相当于Android 的Fragment import { Contact } from '@ohos/Contact'; // 子模块 import { Work } from '@ohos/Work'; // 子模块 import { Mine } from '@ohos/Mine'; // 子模块 import { buttonInfo, ButtonInfoModel } from '../viewmodel/MainPageData'; // 底部导航数据 @Entry @Component struct MainPage { @StorageProp('currentBreakpoint') currentBreakpoint: string = 'sm'; @State currentPageIndex: number = 0; private breakpointSystem = new BreakpointSystem(); aboutToAppear() { this.breakpointSystem.register(); } aboutToDisappear() { this.breakpointSystem.unregister(); } @Builder BottomNavigation(button: ButtonInfoModel) { Column({ space: PageConstants.BUTTON_SPACE }) { // static readonly BUTTON_SPACE: string = '6vp'; Image(this.currentPageIndex === button.index ? button.selectImg : button.img) .objectFit(ImageFit.Contain) .width($r('app.float.main_image_size')) .height($r('app.float.main_image_size')) Text(button.title) .fontColor(this.currentPageIndex === button.index ? $r('app.color.focus_color') : $r('app.color.un_focus_color')) .opacity(this.currentPageIndex === button.index ? StyleConstants.FULL_OPACITY : StyleConstants.SIXTY_OPACITY) .fontWeight(StyleConstants.FONT_WEIGHT_FIVE) .textAlign(TextAlign.Center) .fontSize($r('app.float.micro_font_size')) } .width(StyleConstants.FULL_WIDTH) .height(StyleConstants.FULL_HEIGHT) .alignItems(HorizontalAlign.Center) .justifyContent(FlexAlign.Center) } build() { Column() { Tabs({ barPosition: this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ? BarPosition.Start : BarPosition.End, index: this.currentPageIndex, }) { TabContent() { Chat() // 子模块 }.tabBar(this.BottomNavigation(buttonInfo[0])) TabContent() { Contact() // 子模块 }.tabBar(this.BottomNavigation(buttonInfo[1])) TabContent() { Work() // 子模块 }.tabBar(this.BottomNavigation(buttonInfo[2])) TabContent() { Mine() // 子模块 }.tabBar(this.BottomNavigation(buttonInfo[3])) } .barWidth(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ? $r('app.float.bar_width') : StyleConstants.FULL_WIDTH) .barHeight(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG ? StyleConstants.SIXTY_HEIGHT : $r('app.float.vp_fifty_six')) .vertical(this.currentBreakpoint === BreakpointConstants.BREAKPOINT_LG) .scrollable(false) .onChange((index: number) => { this.currentPageIndex = index; // 提前查询数据 // if (index === 1) { // this.queryShopCart(); // } else if (index === 2) { // this.queryOrderList(); // } }) } .backgroundColor($r('app.color.page_background')) } }
StyleConstants.ets:
/** * Constants for common style. */ export class StyleConstants { /** * Component width percentage: 100%. */ static readonly FULL_WIDTH: string = '100%'; /** * Component height percentage: 100%. */ static readonly FULL_HEIGHT: string = '100%'; /** * Component height percentage: 70%. */ static readonly SEVENTY_HEIGHT: string = '70%'; /** * Component height percentage: 60%. */ static readonly SIXTY_HEIGHT: string = '60%'; /** * Component width percentage: 60%. */ static readonly SIXTY_WIDTH: string = '60%'; /** * Component height percentage: 50%. */ static readonly FIFTY_HEIGHT: string = '50%'; /** * Component height percentage: 50%. */ static readonly HUNDRED_FIFTEEN_WIDTH: string = '115%'; /** * Component space vp : 4. */ static readonly FOUR_SPACE: string = '4vp'; /** * Component space vp : 12. */ static readonly TWELVE_SPACE: string = '12vp'; /** * Component space vp : 14. */ static readonly ITEM_SPACE: string = '14vp'; /** * Component space vp : 15. */ static readonly FIFTEEN_SPACE: string = '15vp'; /** * Font weight value: 700. */ static readonly FONT_WEIGHT_SEVEN: number = 700; /** * Font weight value: 500. */ static readonly FONT_WEIGHT_FIVE: number = 500; /** * Font weight value: 400. */ static readonly FONT_WEIGHT_FOUR: number = 400; /** * Text line value: 2. */ static readonly TWO_TEXT_LINE: number = 2; /** * Component opacity value: 1. */ static readonly FULL_OPACITY: number = 1; /** * Component opacity value: 0.6. */ static readonly SIXTY_OPACITY: number = 0.6; /** * Component opacity value: 0.8. */ static readonly EIGHTY_OPACITY: number = 0.8; /** * Component layout value: 1. */ static readonly LAYOUT_WEIGHT: number = 1; /** * Flex basic value: 1. */ static readonly FLEX_BASIC: number = 1; /** * Flex shrink value: 1. */ static readonly FLEX_SHRINK: number = 1; /** * Flex grow value: 1. */ static readonly FLEX_GROW: number = 1; /** * Swiper or list display count value: 1. */ static readonly DISPLAY_ONE: number = 1; /** * Swiper or list display count value: 2. */ static readonly DISPLAY_TWO: number = 2; /** * Swiper or list display count value: 3. */ static readonly DISPLAY_THREE: number = 3; /** * Swiper or list display count value: 4. */ static readonly DISPLAY_FOUR: number = 4; /** * Image aspect ratio value: 2.23. */ static readonly IMAGE_ASPECT_RATIO: number = 2.25; /** * Number of value: 0.5. */ static readonly HALF_ONE: number = 0.5; /** * Number of value: -1. */ static readonly MINUS_ONE: number = -1; }
import mediaQuery from '@ohos.mediaquery'; import { BreakpointConstants } from '../constants/BreakpointConstants'; declare interface BreakPointTypeOption{ sm?: T md?: T lg?: T xl?: T xxl?: T } /** * 媒体查询(mediaquery) * 响应式设计的核心 */ export class BreakPointType { options: BreakPointTypeOption constructor(option: BreakPointTypeOption ) { this.options = option } getValue(currentBreakPoint: string): T { return this.options[currentBreakPoint] as T } } export class BreakpointSystem { private currentBreakpoint: string = ''; private smListener?: mediaQuery.MediaQueryListener; private mdListener?: mediaQuery.MediaQueryListener; private lgListener?: mediaQuery.MediaQueryListener; private updateCurrentBreakpoint(breakpoint: string) { if (this.currentBreakpoint !== breakpoint) { this.currentBreakpoint = breakpoint; AppStorage.Set (BreakpointConstants.CURRENT_BREAKPOINT, this.currentBreakpoint); } } private isBreakpointSM = (mediaQueryResult: mediaQuery.MediaQueryResult) => { if (mediaQueryResult.matches) { this.updateCurrentBreakpoint(BreakpointConstants.BREAKPOINT_SM); } } private isBreakpointMD = (mediaQueryResult: mediaQuery.MediaQueryResult) => { if (mediaQueryResult.matches) { this.updateCurrentBreakpoint(BreakpointConstants.BREAKPOINT_MD); } } private isBreakpointLG = (mediaQueryResult: mediaQuery.MediaQueryResult) => { if (mediaQueryResult.matches) { this.updateCurrentBreakpoint(BreakpointConstants.BREAKPOINT_LG); } } public register() { this.smListener = mediaQuery.matchMediaSync(BreakpointConstants.RANGE_SM); this.smListener.on('change', this.isBreakpointSM); this.mdListener = mediaQuery.matchMediaSync(BreakpointConstants.RANGE_MD); this.mdListener.on('change', this.isBreakpointMD); this.lgListener = mediaQuery.matchMediaSync(BreakpointConstants.RANGE_LG); this.lgListener.on('change', this.isBreakpointLG); } public unregister() { this.smListener?.off('change', this.isBreakpointSM); this.mdListener?.off('change', this.isBreakpointMD); this.lgListener?.off('change', this.isBreakpointLG); } }
BreakpointConstants.ets:
export class BreakpointConstants { /** * Breakpoints that represent small device types. */ static readonly BREAKPOINT_SM: string = 'sm'; /** * Breakpoints that represent middle device types. */ static readonly BREAKPOINT_MD: string = 'md'; /** * Breakpoints that represent large device types. */ static readonly BREAKPOINT_LG: string = 'lg'; /** * Current breakpoints that to query the device types. */ static readonly CURRENT_BREAKPOINT: string = 'currentBreakpoint'; /** * Range of the small device width. */ static readonly RANGE_SM: string = '(320vp<=width<520vp)'; /** * Range of the middle device width. */ static readonly RANGE_MD: string = '(520vp<=width<840vp)'; /** * Range of the large device width. */ static readonly RANGE_LG: string = '(840vp<=width)'; }
export class ButtonInfoModel { index: number ; // 序号 img: Resource; // 未选中图片 selectImg: Resource ; // 选中图片 title: Resource; // 按钮名称 } const buttonInfo: ButtonInfoModel[] = [ { index: 0, img: $r('app.media.ic_chat_off'), selectImg: $r('app.media.ic_chat_on'), title: $r('app.string.chat') }, { index: 1, img: $r('app.media.ic_contact_off'), selectImg: $r('app.media.ic_contact_on'), title: $r('app.string.contact') }, { index: 2, img: $r('app.media.ic_work_off'), selectImg: $r('app.media.ic_work_on'), title: $r('app.string.work') }, { index: 3, img: $r('app.media.ic_mine_off'), selectImg: $r('app.media.ic_mine_on'), title: $r('app.string.mine') } ] export { buttonInfo }