From 0c9f5ff03b9c1a53a79114c729a876d241abba05 Mon Sep 17 00:00:00 2001 From: Poisoned Date: Tue, 14 Jan 2025 13:48:02 +0000 Subject: [PATCH 1/4] update atomicservicetabs/source/atomicservicetabs.ets. Signed-off-by: Poisoned --- .../source/atomicservicetabs.ets | 169 +++++++++++++++++- 1 file changed, 160 insertions(+), 9 deletions(-) diff --git a/atomicservicetabs/source/atomicservicetabs.ets b/atomicservicetabs/source/atomicservicetabs.ets index 8598e28..cda5590 100644 --- a/atomicservicetabs/source/atomicservicetabs.ets +++ b/atomicservicetabs/source/atomicservicetabs.ets @@ -12,26 +12,165 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { display, mediaquery } from "@kit.ArkUI"; const DEFAULT_BAR_WIDTH: number = 96; -const DEFAULT_BAR_HEIGHT: number = 52; +const DEFAULT_BAR_HEIGHT: number = 48; +const TEXT_WIDTH_HEIGHT_SIZE: number = 24; +const TEXT_FONT_WEIGHT: number = 500; +const TEXT_LIGHT_HEIGHT: number = 14; +const MARGIN_HORIZONTAL_VP: number = 8 +const MARGIN_VERTICAL_VP: number = 4; +const TEXT_SELECTED_COLOR: ResourceColor = $r('sys.color.ohos_id_color_bottom_tab_text_on'); +const TEXT_UNSELECTED_COLOR: ResourceColor = $r('sys.color.ohos_id_color_bottom_tab_text_off'); +const ICON_SELECTED_COLOR: ResourceColor = $r('sys.color.ohos_id_color_bottom_tab_icon'); +const ICON_UNSELECTED_COLOR: ResourceColor = $r('sys.color.ohos_id_color_bottom_tab_icon_off'); @Component export struct AtomicServiceTabs { @BuilderParam tabContents?: [TabContentBuilder?, - TabContentBuilder?, - TabContentBuilder?, - TabContentBuilder?, - TabContentBuilder?]; + TabContentBuilder?, + TabContentBuilder?, + TabContentBuilder?, + TabContentBuilder?]; @Prop tabBarOptionsArray: [TabBarOptions, TabBarOptions, TabBarOptions?, TabBarOptions?, TabBarOptions?]; @Prop tabBarPosition?: TabBarPosition = TabBarPosition.BOTTOM; @Prop barBackgroundColor?: ResourceColor = Color.Transparent; @Prop index?: number | undefined = 0; @Prop barOverlap?: boolean = true; + @Prop layoutMode?: LayoutMode = LayoutMode.VERTICAL; controller?: TabsController = new TabsController(); onChange?: Callback; onTabBarClick?: Callback; onContentWillChange?: OnContentWillChangeCallback; + @State selectedIndex: number = 0; + @State layoutModelStatue: boolean = false; + @State widthFlag: boolean = false; + @State landStatus: boolean = false; + @State barHeight?: Length = undefined; + @State barModeStatus: BarMode = BarMode.Fixed; + @State iconTextStatus: boolean = false; + @State directionStatus: FlexDirection = FlexDirection.Column; + @State textMarginTop?: number = undefined; + @State textMarginLeft?: number = undefined; + @State tabMargin?: number = undefined; + @State tabPadding?: number = MARGIN_VERTICAL_VP; + listener: mediaquery.MediaQueryListener = + this.getUIContext().getMediaQuery().matchMediaSync('(orientation: landscape)'); + + aboutToAppear() { + this.initBarWidthAndHeight() + if (this.iconTextStatus && this.layoutMode === LayoutMode.AUTO && this.tabBarPosition === TabBarPosition.BOTTOM) { + this.landStatus = this.listener.matches; + this.foldListener(); + this.startListener(); + } + } + + aboutToDisappear(): void { + this.listener.off('change'); + display.off('foldDisplayModeChange'); + } + + initBarWidthAndHeight() { + this.layoutModelStatue = (this.layoutMode === LayoutMode.HORIZONTAL) ? true : false; + if (this.tabBarOptionsArray[0].icon && this.tabBarOptionsArray[0].text) { + this.iconTextStatus = true; + } + if (this.tabBarPosition === TabBarPosition.LEFT) { + this.barModeStatus = BarMode.Scrollable; + this.barHeight = (50 / this.tabBarOptionsArray.length + '%'); + } + this.buildTab(); + } + + getScreenInfo() { + const screenWidth = px2vp(display.getDefaultDisplaySync().width); + this.widthFlag = screenWidth / this.tabBarOptionsArray.length > 104 ? true : false; + } + + foldListener() { + if (display.isFoldable()) { + display.on('foldDisplayModeChange', (data: display.FoldDisplayMode) => { + this.getScreenInfo(); + this.initLayoutStatus(); + }); + } + } + + startListener() { + this.listener.on('change', (mediaQueryResult: mediaquery.MediaQueryResult) => { + this.landStatus = mediaQueryResult.matches; + this.getScreenInfo(); + this.initLayoutStatus(); + }); + } + + initLayoutStatus() { + this.layoutModelStatue = (this.landStatus || this.widthFlag) ? true : false; + this.buildTab(); + } + + buildTab() { + this.directionStatus = this.layoutModelStatue ? FlexDirection.Row : FlexDirection.Column; + if (this.iconTextStatus) { + this.textMarginTop = this.layoutModelStatue ? undefined : MARGIN_VERTICAL_VP; + this.textMarginLeft = this.layoutModelStatue ? MARGIN_HORIZONTAL_VP : undefined; + this.tabPadding = this.layoutModelStatue ? undefined : MARGIN_VERTICAL_VP; + this.tabMargin = this.layoutModelStatue ? MARGIN_HORIZONTAL_VP : undefined; + } + } + + getColor(userColor: ResourceColor, defaultColor: ResourceColor): ResourceColor { + return userColor ? userColor : defaultColor; + } + + getFontSize(): Resource { + return this.layoutModelStatue ? $r('sys.float.ohos_id_text_size_button3') : + (this.iconTextStatus ? $r('sys.float.ohos_id_text_size_caption') : + $r('sys.float.ohos_id_text_size_button3')); + } + + @Builder + TabBuilder(item: TabBarOptions, index: number) { + Flex({ + direction: this.directionStatus, + alignItems: ItemAlign.Center, + justifyContent: FlexAlign.Center + }) { + if (item.icon) { + Image(item.icon as ResourceStr) + .width(TEXT_WIDTH_HEIGHT_SIZE) + .height(TEXT_WIDTH_HEIGHT_SIZE) + .objectFit(ImageFit.Contain) + .fillColor(this.selectedIndex === index ? this.getColor(item.selectedColor, ICON_SELECTED_COLOR) + : this.getColor(item.unselectedColor, ICON_UNSELECTED_COLOR)) + .backgroundColor(Color.Transparent) + .flexShrink(0) + } + if (item.text) { + Text(item.text) + .textOverflow({ overflow: TextOverflow.Ellipsis }) + .maxLines(1) + .fontColor(this.selectedIndex === index ? this.getColor(item.selectedColor, TEXT_SELECTED_COLOR) + : this.getColor(item.unselectedColor, TEXT_UNSELECTED_COLOR)) + .maxFontSize(this.getFontSize()) + .minFontSize(9) + .fontWeight(TEXT_FONT_WEIGHT) + .lineHeight(TEXT_LIGHT_HEIGHT) + .textAlign(TextAlign.Center) + .focusOnTouch(true) + .backgroundColor(Color.Transparent) + .margin({ + top: this.textMarginTop, + left: this.textMarginLeft + }) + } + } + .padding({ left: this.tabPadding, right: this.tabPadding }) + .margin({ left: this.tabMargin, right: this.tabMargin }) + .height(this.barHeight) + } build() { Tabs({ @@ -46,23 +185,35 @@ export struct AtomicServiceTabs { this.tabContents[index]?.() } } - .tabBar(BottomTabBarStyle.of(item.icon, item.text) - .labelStyle({ unselectedColor: item.unselectedColor, selectedColor: item.selectedColor }) - .iconStyle({ unselectedColor: item.unselectedColor, selectedColor: item.selectedColor })) + .tabBar( + this.TabBuilder(item, index) + ) .width((!this.tabContents && this.tabBarPosition === TabBarPosition.LEFT) ? DEFAULT_BAR_WIDTH : '100%') .height((!this.tabContents && this.tabBarPosition === TabBarPosition.BOTTOM) ? DEFAULT_BAR_HEIGHT : '100%') } }) } + .safeAreaPadding({ + bottom: 0 + }) + .animationDuration(0) .barBackgroundColor(this.barBackgroundColor) .divider(null) + .barMode(this.barModeStatus) .vertical(this.tabBarPosition === TabBarPosition.LEFT ? true : false) .scrollable(false) .barOverlap(this.barOverlap) .barBackgroundBlurStyle(BlurStyle.COMPONENT_THICK) - .onChange(this.onChange) + .onChange((index: number) => { + if (this.onChange) { + this.onChange(index); + } + this.selectedIndex = index; + }) .onTabBarClick(this.onTabBarClick) .onContentWillChange(this.onContentWillChange) + .barWidth((this.tabBarPosition === TabBarPosition.LEFT) ? DEFAULT_BAR_WIDTH : '100%') + .barHeight((this.tabBarPosition === TabBarPosition.BOTTOM) ? DEFAULT_BAR_HEIGHT : '100%') .width((!this.tabContents && this.tabBarPosition === TabBarPosition.LEFT) ? DEFAULT_BAR_WIDTH : '100%') .height((!this.tabContents && this.tabBarPosition === TabBarPosition.BOTTOM) ? DEFAULT_BAR_HEIGHT : '100%') } -- Gitee From b146ad3d68aabe88ae111ad151f38ef1d7b9e369 Mon Sep 17 00:00:00 2001 From: Poisoned Date: Tue, 14 Jan 2025 13:48:38 +0000 Subject: [PATCH 2/4] update atomicservicetabs/interfaces/atomicservicetabs.js. Signed-off-by: Poisoned --- .../interfaces/atomicservicetabs.js | 75 ++++++++++++++++++- 1 file changed, 72 insertions(+), 3 deletions(-) diff --git a/atomicservicetabs/interfaces/atomicservicetabs.js b/atomicservicetabs/interfaces/atomicservicetabs.js index 172d3fb..d505857 100644 --- a/atomicservicetabs/interfaces/atomicservicetabs.js +++ b/atomicservicetabs/interfaces/atomicservicetabs.js @@ -18,6 +18,13 @@ if (!("finalizeConstruction" in ViewPU.prototype)) { } const DEFAULT_BAR_WIDTH = 96; const DEFAULT_BAR_HEIGHT = 52; +const TEXT_WIDTH_HEIGHT_SIZE = 24; +const TEXT_FONT_WEIGHT = 500; +const TEXT_LIGHT_HEIGHT = 14; +const TEXT_SELECTED_COLOR = { "id": -1, "type": 10001, params: ['sys.color.ohos_id_color_bottom_tab_text_on'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" }; +const TEXT_UNSELECTED_COLOR = { "id": -1, "type": 10001, params: ['sys.color.ohos_id_color_bottom_tab_text_off'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" }; +const ICON_SELECTED_COLOR = { "id": -1, "type": 10001, params: ['sys.color.ohos_id_color_bottom_tab_icon'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" }; +const ICON_UNSELECTED_COLOR = { "id": -1, "type": 10001, params: ['sys.color.ohos_id_color_bottom_tab_icon_off'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" }; export class AtomicServiceTabs extends ViewPU { constructor(m1, n1, o1, p1 = -1, q1 = undefined, r1) { super(m1, o1, p1, r1); @@ -119,6 +126,68 @@ export class AtomicServiceTabs extends ViewPU { set barOverlap(e1) { this.__barOverlap.set(e1); } + getColor(userColor, defaultColor) { + return userColor ? userColor : defaultColor; + } + getFontSize(item) { + return item.icon && item.text ? { "id": -1, "type": 10002, params: ['sys.float.ohos_id_text_size_caption'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" } : { "id": -1, "type": 10002, params: ['sys.float.ohos_id_text_size_button3'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" }; + } + TabBuilder(item, index, parent = null) { + this.observeComponentCreation2((elmtId, isInitialRender) => { + Column.create(); + Column.width('100%'); + }, Column); + this.observeComponentCreation2((elmtId, isInitialRender) => { + If.create(); + if (item.icon) { + this.ifElseBranchUpdateFunction(0, () => { + this.observeComponentCreation2((elmtId, isInitialRender) => { + Image.create(item.icon); + Image.width(TEXT_WIDTH_HEIGHT_SIZE); + Image.height(TEXT_WIDTH_HEIGHT_SIZE); + Image.margin({ bottom: 4 }); + Image.objectFit(ImageFit.Contain); + Image.fillColor(this.selectedIndex === index ? this.getColor(item.selectedColor, ICON_SELECTED_COLOR) + : this.getColor(item.unselectedColor, ICON_UNSELECTED_COLOR)); + Image.backgroundColor(Color.Transparent); + }, Image); + }); + } + else { + this.ifElseBranchUpdateFunction(1, () => { + }); + } + }, If); + If.pop(); + this.observeComponentCreation2((elmtId, isInitialRender) => { + If.create(); + if (item.text) { + this.ifElseBranchUpdateFunction(0, () => { + this.observeComponentCreation2((elmtId, isInitialRender) => { + Text.create(item.text); + Text.textOverflow({ overflow: TextOverflow.Ellipsis }); + Text.maxLines(1); + Text.fontColor(this.selectedIndex === index ? this.getColor(item.selectedColor, TEXT_SELECTED_COLOR) + : this.getColor(item.unselectedColor, TEXT_UNSELECTED_COLOR)); + Text.maxFontSize(this.getFontSize(item)); + Text.minFontSize(9); + Text.fontWeight(TEXT_FONT_WEIGHT); + Text.lineHeight(TEXT_LIGHT_HEIGHT); + Text.textAlign(TextAlign.Center); + Text.focusOnTouch(true); + Text.padding({ left: 4, right: 4 }); + }, Text); + Text.pop(); + }); + } + else { + this.ifElseBranchUpdateFunction(1, () => { + }); + } + }, If); + If.pop(); + Column.pop(); + } initialRender() { this.observeComponentCreation2((c1, d1) => { Tabs.create({ @@ -162,9 +231,9 @@ export class AtomicServiceTabs extends ViewPU { }, If); If.pop(); }); - TabContent.tabBar(BottomTabBarStyle.of(n.icon, n.text) - .labelStyle({ unselectedColor: n.unselectedColor, selectedColor: n.selectedColor }) - .iconStyle({ unselectedColor: n.unselectedColor, selectedColor: n.selectedColor })); + TabContent.tabBar({ builder: () => { + this.TabBuilder.call(this, item, index); + } }); TabContent.width((!this.tabContents && this.tabBarPosition === TabBarPosition.LEFT) ? DEFAULT_BAR_WIDTH : '100%'); TabContent.height((!this.tabContents && this.tabBarPosition === TabBarPosition.BOTTOM) ? DEFAULT_BAR_HEIGHT : '100%'); }, TabContent); -- Gitee From a03ddb00e3905d7750c340ff0771d625c8c0442f Mon Sep 17 00:00:00 2001 From: Poisoned Date: Wed, 15 Jan 2025 06:40:28 +0000 Subject: [PATCH 3/4] update atomicservicetabs/source/atomicservicetabs.ets. Signed-off-by: Poisoned --- .../source/atomicservicetabs.ets | 85 +++++++------------ 1 file changed, 32 insertions(+), 53 deletions(-) diff --git a/atomicservicetabs/source/atomicservicetabs.ets b/atomicservicetabs/source/atomicservicetabs.ets index cda5590..0a63a3d 100644 --- a/atomicservicetabs/source/atomicservicetabs.ets +++ b/atomicservicetabs/source/atomicservicetabs.ets @@ -21,10 +21,6 @@ const TEXT_FONT_WEIGHT: number = 500; const TEXT_LIGHT_HEIGHT: number = 14; const MARGIN_HORIZONTAL_VP: number = 8 const MARGIN_VERTICAL_VP: number = 4; -const TEXT_SELECTED_COLOR: ResourceColor = $r('sys.color.ohos_id_color_bottom_tab_text_on'); -const TEXT_UNSELECTED_COLOR: ResourceColor = $r('sys.color.ohos_id_color_bottom_tab_text_off'); -const ICON_SELECTED_COLOR: ResourceColor = $r('sys.color.ohos_id_color_bottom_tab_icon'); -const ICON_UNSELECTED_COLOR: ResourceColor = $r('sys.color.ohos_id_color_bottom_tab_icon_off'); @Component export struct AtomicServiceTabs { @@ -43,26 +39,22 @@ export struct AtomicServiceTabs { onChange?: Callback; onTabBarClick?: Callback; onContentWillChange?: OnContentWillChangeCallback; - @State selectedIndex: number = 0; - @State layoutModelStatue: boolean = false; - @State widthFlag: boolean = false; - @State landStatus: boolean = false; - @State barHeight?: Length = undefined; - @State barModeStatus: BarMode = BarMode.Fixed; - @State iconTextStatus: boolean = false; - @State directionStatus: FlexDirection = FlexDirection.Column; - @State textMarginTop?: number = undefined; - @State textMarginLeft?: number = undefined; - @State tabMargin?: number = undefined; - @State tabPadding?: number = MARGIN_VERTICAL_VP; + @State private selectedIndex: number = 0; + @State private isHorizontal: boolean = false; + @State private barModeStatus: BarMode = BarMode.Fixed; + @State private directionStatus: FlexDirection = FlexDirection.Column; + @State private textMarginTop?: number = undefined; + @State private textMarginLeft?: number = undefined; + @State private tabMargin?: number = undefined; + @State private tabPadding?: number = MARGIN_VERTICAL_VP; + private isIconAndText: boolean = false; + private barHeight?: Length = undefined; listener: mediaquery.MediaQueryListener = this.getUIContext().getMediaQuery().matchMediaSync('(orientation: landscape)'); aboutToAppear() { - this.initBarWidthAndHeight() - if (this.iconTextStatus && this.layoutMode === LayoutMode.AUTO && this.tabBarPosition === TabBarPosition.BOTTOM) { - this.landStatus = this.listener.matches; - this.foldListener(); + this.initBarModeAndHeight() + if (this.isIconAndText && this.layoutMode === LayoutMode.AUTO && this.tabBarPosition === TabBarPosition.BOTTOM) { this.startListener(); } } @@ -72,10 +64,10 @@ export struct AtomicServiceTabs { display.off('foldDisplayModeChange'); } - initBarWidthAndHeight() { - this.layoutModelStatue = (this.layoutMode === LayoutMode.HORIZONTAL) ? true : false; + initBarModeAndHeight() { + this.isHorizontal = (this.layoutMode === LayoutMode.HORIZONTAL) ? true : false; if (this.tabBarOptionsArray[0].icon && this.tabBarOptionsArray[0].text) { - this.iconTextStatus = true; + this.isIconAndText = true; } if (this.tabBarPosition === TabBarPosition.LEFT) { this.barModeStatus = BarMode.Scrollable; @@ -84,50 +76,38 @@ export struct AtomicServiceTabs { this.buildTab(); } - getScreenInfo() { - const screenWidth = px2vp(display.getDefaultDisplaySync().width); - this.widthFlag = screenWidth / this.tabBarOptionsArray.length > 104 ? true : false; - } - - foldListener() { + startListener() { if (display.isFoldable()) { display.on('foldDisplayModeChange', (data: display.FoldDisplayMode) => { - this.getScreenInfo(); this.initLayoutStatus(); }); } - } - - startListener() { this.listener.on('change', (mediaQueryResult: mediaquery.MediaQueryResult) => { - this.landStatus = mediaQueryResult.matches; - this.getScreenInfo(); this.initLayoutStatus(); }); } initLayoutStatus() { - this.layoutModelStatue = (this.landStatus || this.widthFlag) ? true : false; + const screenWidth = px2vp(display.getDefaultDisplaySync().width); + const widthFlag = screenWidth / this.tabBarOptionsArray.length > 104 ? true : false; + console.log('widthFlag=== ', widthFlag) + this.isHorizontal = widthFlag ? true : false; this.buildTab(); } buildTab() { - this.directionStatus = this.layoutModelStatue ? FlexDirection.Row : FlexDirection.Column; - if (this.iconTextStatus) { - this.textMarginTop = this.layoutModelStatue ? undefined : MARGIN_VERTICAL_VP; - this.textMarginLeft = this.layoutModelStatue ? MARGIN_HORIZONTAL_VP : undefined; - this.tabPadding = this.layoutModelStatue ? undefined : MARGIN_VERTICAL_VP; - this.tabMargin = this.layoutModelStatue ? MARGIN_HORIZONTAL_VP : undefined; + this.directionStatus = this.isHorizontal ? FlexDirection.Row : FlexDirection.Column; + if (this.isIconAndText) { + this.textMarginTop = this.isHorizontal ? undefined : MARGIN_VERTICAL_VP; + this.textMarginLeft = this.isHorizontal ? MARGIN_HORIZONTAL_VP : undefined; + this.tabPadding = this.isHorizontal ? undefined : MARGIN_VERTICAL_VP; + this.tabMargin = this.isHorizontal ? MARGIN_HORIZONTAL_VP : undefined; } } - getColor(userColor: ResourceColor, defaultColor: ResourceColor): ResourceColor { - return userColor ? userColor : defaultColor; - } - getFontSize(): Resource { - return this.layoutModelStatue ? $r('sys.float.ohos_id_text_size_button3') : - (this.iconTextStatus ? $r('sys.float.ohos_id_text_size_caption') : + return this.isHorizontal ? $r('sys.float.ohos_id_text_size_button3') : + (this.isIconAndText ? $r('sys.float.ohos_id_text_size_caption') : $r('sys.float.ohos_id_text_size_button3')); } @@ -143,8 +123,7 @@ export struct AtomicServiceTabs { .width(TEXT_WIDTH_HEIGHT_SIZE) .height(TEXT_WIDTH_HEIGHT_SIZE) .objectFit(ImageFit.Contain) - .fillColor(this.selectedIndex === index ? this.getColor(item.selectedColor, ICON_SELECTED_COLOR) - : this.getColor(item.unselectedColor, ICON_UNSELECTED_COLOR)) + .fillColor(this.selectedIndex === index ? item.selectedColor : item.unselectedColor) .backgroundColor(Color.Transparent) .flexShrink(0) } @@ -152,8 +131,7 @@ export struct AtomicServiceTabs { Text(item.text) .textOverflow({ overflow: TextOverflow.Ellipsis }) .maxLines(1) - .fontColor(this.selectedIndex === index ? this.getColor(item.selectedColor, TEXT_SELECTED_COLOR) - : this.getColor(item.unselectedColor, TEXT_UNSELECTED_COLOR)) + .fontColor(this.selectedIndex === index ? item.selectedColor : item.unselectedColor) .maxFontSize(this.getFontSize()) .minFontSize(9) .fontWeight(TEXT_FONT_WEIGHT) @@ -226,7 +204,7 @@ export class TabBarOptions { public selectedColor?: ResourceColor; constructor(icon: ResourceStr | TabBarSymbol, text: ResourceStr, - unselectedColor?: ResourceColor, selectedColor?: ResourceColor) { + unselectedColor?: ResourceColor, selectedColor?: ResourceColor) { this.icon = icon; this.text = text; this.unselectedColor = unselectedColor; @@ -240,4 +218,5 @@ export enum TabBarPosition { } export type TabContentBuilder = () => void; + export type OnContentWillChangeCallback = (currentIndex: number, comingIndex: number) => boolean; \ No newline at end of file -- Gitee From d1ed3cc2750172e215b02a854e7e3dac33d193f9 Mon Sep 17 00:00:00 2001 From: Poisoned Date: Wed, 15 Jan 2025 06:41:21 +0000 Subject: [PATCH 4/4] update atomicservicetabs/interfaces/atomicservicetabs.js. Signed-off-by: Poisoned --- .../interfaces/atomicservicetabs.js | 231 ++++++++++++++++-- 1 file changed, 208 insertions(+), 23 deletions(-) diff --git a/atomicservicetabs/interfaces/atomicservicetabs.js b/atomicservicetabs/interfaces/atomicservicetabs.js index d505857..8873cee 100644 --- a/atomicservicetabs/interfaces/atomicservicetabs.js +++ b/atomicservicetabs/interfaces/atomicservicetabs.js @@ -16,15 +16,14 @@ if (!("finalizeConstruction" in ViewPU.prototype)) { Reflect.set(ViewPU.prototype, "finalizeConstruction", () => { }); } +import display from "@ohos.display"; const DEFAULT_BAR_WIDTH = 96; -const DEFAULT_BAR_HEIGHT = 52; +const DEFAULT_BAR_HEIGHT = 48; const TEXT_WIDTH_HEIGHT_SIZE = 24; const TEXT_FONT_WEIGHT = 500; const TEXT_LIGHT_HEIGHT = 14; -const TEXT_SELECTED_COLOR = { "id": -1, "type": 10001, params: ['sys.color.ohos_id_color_bottom_tab_text_on'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" }; -const TEXT_UNSELECTED_COLOR = { "id": -1, "type": 10001, params: ['sys.color.ohos_id_color_bottom_tab_text_off'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" }; -const ICON_SELECTED_COLOR = { "id": -1, "type": 10001, params: ['sys.color.ohos_id_color_bottom_tab_icon'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" }; -const ICON_UNSELECTED_COLOR = { "id": -1, "type": 10001, params: ['sys.color.ohos_id_color_bottom_tab_icon_off'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" }; +const MARGIN_HORIZONTAL_VP = 8; +const MARGIN_VERTICAL_VP = 4; export class AtomicServiceTabs extends ViewPU { constructor(m1, n1, o1, p1 = -1, q1 = undefined, r1) { super(m1, o1, p1, r1); @@ -37,10 +36,22 @@ export class AtomicServiceTabs extends ViewPU { this.__barBackgroundColor = new SynchedPropertyObjectOneWayPU(n1.barBackgroundColor, this, "barBackgroundColor"); this.__index = new SynchedPropertyObjectOneWayPU(n1.index, this, "index"); this.__barOverlap = new SynchedPropertySimpleOneWayPU(n1.barOverlap, this, "barOverlap"); + this.__layoutMode = new SynchedPropertySimpleOneWayPU(n1.layoutMode, this, "layoutMode"); this.controller = new TabsController(); this.onChange = undefined; this.onTabBarClick = undefined; this.onContentWillChange = undefined; + this.__selectedIndex = new ObservedPropertySimplePU(0, this, "selectedIndex"); + this.__isHorizontal = new ObservedPropertySimplePU(false, this, "isHorizontal"); + this.__barModeStatus = new ObservedPropertySimplePU(BarMode.Fixed, this, "barModeStatus"); + this.__directionStatus = new ObservedPropertySimplePU(FlexDirection.Column, this, "directionStatus"); + this.__textMarginTop = new ObservedPropertySimplePU(undefined, this, "textMarginTop"); + this.__textMarginLeft = new ObservedPropertySimplePU(undefined, this, "textMarginLeft"); + this.__tabMargin = new ObservedPropertySimplePU(undefined, this, "tabMargin"); + this.__tabPadding = new ObservedPropertySimplePU(MARGIN_VERTICAL_VP, this, "tabPadding"); + this.isIconAndText = false; + this.barHeight = undefined; + this.listener = this.getUIContext().getMediaQuery().matchMediaSync('(orientation: landscape)'); this.setInitiallyProvidedValue(n1); this.finalizeConstruction(); } @@ -60,6 +71,9 @@ export class AtomicServiceTabs extends ViewPU { if (l1.barOverlap === undefined) { this.__barOverlap.set(true); } + if (l1.layoutMode === undefined) { + this.__layoutMode.set(LayoutMode.VERTICAL); + } if (l1.controller !== undefined) { this.controller = l1.controller; } @@ -72,6 +86,39 @@ export class AtomicServiceTabs extends ViewPU { if (l1.onContentWillChange !== undefined) { this.onContentWillChange = l1.onContentWillChange; } + if (l1.selectedIndex !== undefined) { + this.selectedIndex = l1.selectedIndex; + } + if (l1.isHorizontal !== undefined) { + this.isHorizontal = l1.isHorizontal; + } + if (l1.barModeStatus !== undefined) { + this.barModeStatus = l1.barModeStatus; + } + if (l1.directionStatus !== undefined) { + this.directionStatus = l1.directionStatus; + } + if (l1.textMarginTop !== undefined) { + this.textMarginTop = l1.textMarginTop; + } + if (l1.textMarginLeft !== undefined) { + this.textMarginLeft = l1.textMarginLeft; + } + if (l1.tabMargin !== undefined) { + this.tabMargin = l1.tabMargin; + } + if (l1.tabPadding !== undefined) { + this.tabPadding = l1.tabPadding; + } + if (l1.isIconAndText !== undefined) { + this.isIconAndText = l1.isIconAndText; + } + if (l1.barHeight !== undefined) { + this.barHeight = l1.barHeight; + } + if (l1.listener !== undefined) { + this.listener = l1.listener; + } } updateStateVars(k1) { this.__tabBarOptionsArray.reset(k1.tabBarOptionsArray); @@ -79,6 +126,7 @@ export class AtomicServiceTabs extends ViewPU { this.__barBackgroundColor.reset(k1.barBackgroundColor); this.__index.reset(k1.index); this.__barOverlap.reset(k1.barOverlap); + this.__layoutMode.reset(k1.layoutMode); } purgeVariableDependenciesOnElmtId(j1) { this.__tabBarOptionsArray.purgeDependencyOnElmtId(j1); @@ -86,6 +134,15 @@ export class AtomicServiceTabs extends ViewPU { this.__barBackgroundColor.purgeDependencyOnElmtId(j1); this.__index.purgeDependencyOnElmtId(j1); this.__barOverlap.purgeDependencyOnElmtId(j1); + this.__layoutMode.purgeDependencyOnElmtId(j1); + this.__selectedIndex.purgeDependencyOnElmtId(j1); + this.__isHorizontal.purgeDependencyOnElmtId(j1); + this.__barModeStatus.purgeDependencyOnElmtId(j1); + this.__directionStatus.purgeDependencyOnElmtId(j1); + this.__textMarginTop.purgeDependencyOnElmtId(j1); + this.__textMarginLeft.purgeDependencyOnElmtId(j1); + this.__tabMargin.purgeDependencyOnElmtId(j1); + this.__tabPadding.purgeDependencyOnElmtId(j1); } aboutToBeDeleted() { this.__tabBarOptionsArray.aboutToBeDeleted(); @@ -93,6 +150,15 @@ export class AtomicServiceTabs extends ViewPU { this.__barBackgroundColor.aboutToBeDeleted(); this.__index.aboutToBeDeleted(); this.__barOverlap.aboutToBeDeleted(); + this.__layoutMode.aboutToBeDeleted(); + this.__selectedIndex.aboutToBeDeleted(); + this.__isHorizontal.aboutToBeDeleted(); + this.__barModeStatus.aboutToBeDeleted(); + this.__directionStatus.aboutToBeDeleted(); + this.__textMarginTop.aboutToBeDeleted(); + this.__textMarginLeft.aboutToBeDeleted(); + this.__tabMargin.aboutToBeDeleted(); + this.__tabPadding.aboutToBeDeleted(); SubscriberManager.Get().delete(this.id__()); this.aboutToBeDeletedInternal(); } @@ -126,17 +192,122 @@ export class AtomicServiceTabs extends ViewPU { set barOverlap(e1) { this.__barOverlap.set(e1); } - getColor(userColor, defaultColor) { - return userColor ? userColor : defaultColor; + get layoutMode() { + return this.__layoutMode.get(); + } + set layoutMode(newValue) { + this.__layoutMode.set(newValue); + } + get selectedIndex() { + return this.__selectedIndex.get(); + } + set selectedIndex(newValue) { + this.__selectedIndex.set(newValue); + } + get isHorizontal() { + return this.__isHorizontal.get(); + } + set isHorizontal(newValue) { + this.__isHorizontal.set(newValue); + } + get barModeStatus() { + return this.__barModeStatus.get(); + } + set barModeStatus(newValue) { + this.__barModeStatus.set(newValue); + } + get directionStatus() { + return this.__directionStatus.get(); + } + set directionStatus(newValue) { + this.__directionStatus.set(newValue); + } + get textMarginTop() { + return this.__textMarginTop.get(); + } + set textMarginTop(newValue) { + this.__textMarginTop.set(newValue); } - getFontSize(item) { - return item.icon && item.text ? { "id": -1, "type": 10002, params: ['sys.float.ohos_id_text_size_caption'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" } : { "id": -1, "type": 10002, params: ['sys.float.ohos_id_text_size_button3'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" }; + get textMarginLeft() { + return this.__textMarginLeft.get(); + } + set textMarginLeft(newValue) { + this.__textMarginLeft.set(newValue); + } + get tabMargin() { + return this.__tabMargin.get(); + } + set tabMargin(newValue) { + this.__tabMargin.set(newValue); + } + get tabPadding() { + return this.__tabPadding.get(); + } + set tabPadding(newValue) { + this.__tabPadding.set(newValue); + } + aboutToAppear() { + this.initBarModeAndHeight(); + if (this.isIconAndText && this.layoutMode === LayoutMode.AUTO && this.tabBarPosition === TabBarPosition.BOTTOM) { + this.startListener(); + } + } + aboutToDisappear() { + this.listener.off('change'); + display.off('foldDisplayModeChange'); + } + initBarModeAndHeight() { + this.isHorizontal = (this.layoutMode === LayoutMode.HORIZONTAL) ? true : false; + if (this.tabBarOptionsArray[0].icon && this.tabBarOptionsArray[0].text) { + this.isIconAndText = true; + } + if (this.tabBarPosition === TabBarPosition.LEFT) { + this.barModeStatus = BarMode.Scrollable; + this.barHeight = (50 / this.tabBarOptionsArray.length + '%'); + } + this.buildTab(); + } + startListener() { + if (display.isFoldable()) { + display.on('foldDisplayModeChange', (data) => { + this.initLayoutStatus(); + }); + } + this.listener.on('change', (mediaQueryResult) => { + this.initLayoutStatus(); + }); + } + initLayoutStatus() { + const screenWidth = px2vp(display.getDefaultDisplaySync().width); + const widthFlag = screenWidth / this.tabBarOptionsArray.length > 104 ? true : false; + console.log('widthFlag=== ', widthFlag); + this.isHorizontal = widthFlag ? true : false; + this.buildTab(); + } + buildTab() { + this.directionStatus = this.isHorizontal ? FlexDirection.Row : FlexDirection.Column; + if (this.isIconAndText) { + this.textMarginTop = this.isHorizontal ? undefined : MARGIN_VERTICAL_VP; + this.textMarginLeft = this.isHorizontal ? MARGIN_HORIZONTAL_VP : undefined; + this.tabPadding = this.isHorizontal ? undefined : MARGIN_VERTICAL_VP; + this.tabMargin = this.isHorizontal ? MARGIN_HORIZONTAL_VP : undefined; + } + } + getFontSize() { + return this.isHorizontal ? { "id": -1, "type": 10002, params: ['sys.float.ohos_id_text_size_button3'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" } : + (this.isIconAndText ? { "id": -1, "type": 10002, params: ['sys.float.ohos_id_text_size_caption'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" } : { "id": -1, "type": 10002, params: ['sys.float.ohos_id_text_size_button3'], "bundleName": "__harDefaultBundleName__", "moduleName": "__harDefaultModuleName__" }); } TabBuilder(item, index, parent = null) { this.observeComponentCreation2((elmtId, isInitialRender) => { - Column.create(); - Column.width('100%'); - }, Column); + Flex.create({ + direction: this.directionStatus, + alignItems: ItemAlign.Center, + justifyContent: FlexAlign.Center + }); + Flex.padding({ left: this.tabPadding, right: this.tabPadding }); + Flex.margin({ left: this.tabMargin, right: this.tabMargin }); + Flex.height(this.barHeight); + }, Flex); this.observeComponentCreation2((elmtId, isInitialRender) => { If.create(); if (item.icon) { @@ -145,11 +316,10 @@ export class AtomicServiceTabs extends ViewPU { Image.create(item.icon); Image.width(TEXT_WIDTH_HEIGHT_SIZE); Image.height(TEXT_WIDTH_HEIGHT_SIZE); - Image.margin({ bottom: 4 }); Image.objectFit(ImageFit.Contain); - Image.fillColor(this.selectedIndex === index ? this.getColor(item.selectedColor, ICON_SELECTED_COLOR) - : this.getColor(item.unselectedColor, ICON_UNSELECTED_COLOR)); + Image.fillColor(this.selectedIndex === index ? item.selectedColor : item.unselectedColor); Image.backgroundColor(Color.Transparent); + Image.flexShrink(0); }, Image); }); } @@ -167,15 +337,18 @@ export class AtomicServiceTabs extends ViewPU { Text.create(item.text); Text.textOverflow({ overflow: TextOverflow.Ellipsis }); Text.maxLines(1); - Text.fontColor(this.selectedIndex === index ? this.getColor(item.selectedColor, TEXT_SELECTED_COLOR) - : this.getColor(item.unselectedColor, TEXT_UNSELECTED_COLOR)); - Text.maxFontSize(this.getFontSize(item)); + Text.fontColor(this.selectedIndex === index ? item.selectedColor : item.unselectedColor); + Text.maxFontSize(this.getFontSize()); Text.minFontSize(9); Text.fontWeight(TEXT_FONT_WEIGHT); Text.lineHeight(TEXT_LIGHT_HEIGHT); Text.textAlign(TextAlign.Center); Text.focusOnTouch(true); - Text.padding({ left: 4, right: 4 }); + Text.backgroundColor(Color.Transparent); + Text.margin({ + top: this.textMarginTop, + left: this.textMarginLeft + }); }, Text); Text.pop(); }); @@ -186,7 +359,7 @@ export class AtomicServiceTabs extends ViewPU { } }, If); If.pop(); - Column.pop(); + Flex.pop(); } initialRender() { this.observeComponentCreation2((c1, d1) => { @@ -195,15 +368,27 @@ export class AtomicServiceTabs extends ViewPU { index: this.index, controller: this.controller }); + Tabs.safeAreaPadding({ + bottom: 0 + }); + Tabs.animationDuration(0); Tabs.barBackgroundColor(ObservedObject.GetRawObject(this.barBackgroundColor)); Tabs.divider(null); + Tabs.barMode(this.barModeStatus); Tabs.vertical(this.tabBarPosition === TabBarPosition.LEFT ? true : false); Tabs.scrollable(false); Tabs.barOverlap(this.barOverlap); Tabs.barBackgroundBlurStyle(BlurStyle.COMPONENT_THICK); - Tabs.onChange(this.onChange); + Tabs.onChange((index) => { + if (this.onChange) { + this.onChange(index); + } + this.selectedIndex = index; + }); Tabs.onTabBarClick(this.onTabBarClick); Tabs.onContentWillChange(this.onContentWillChange); + Tabs.barWidth((this.tabBarPosition === TabBarPosition.LEFT) ? DEFAULT_BAR_WIDTH : '100%'); + Tabs.barHeight((this.tabBarPosition === TabBarPosition.BOTTOM) ? DEFAULT_BAR_HEIGHT : '100%'); Tabs.width((!this.tabContents && this.tabBarPosition === TabBarPosition.LEFT) ? DEFAULT_BAR_WIDTH : '100%'); Tabs.height((!this.tabContents && this.tabBarPosition === TabBarPosition.BOTTOM) ? DEFAULT_BAR_HEIGHT : '100%'); }, Tabs); @@ -232,8 +417,8 @@ export class AtomicServiceTabs extends ViewPU { If.pop(); }); TabContent.tabBar({ builder: () => { - this.TabBuilder.call(this, item, index); - } }); + this.TabBuilder.call(this, item, index); + } }); TabContent.width((!this.tabContents && this.tabBarPosition === TabBarPosition.LEFT) ? DEFAULT_BAR_WIDTH : '100%'); TabContent.height((!this.tabContents && this.tabBarPosition === TabBarPosition.BOTTOM) ? DEFAULT_BAR_HEIGHT : '100%'); }, TabContent); -- Gitee