HarmonyOS 鸿蒙Next ArkUI中Tabs组件如何设置标签栏背景图

发布于 1周前 作者 sinazl 来自 鸿蒙OS

HarmonyOS 鸿蒙Next ArkUI中Tabs组件如何设置标签栏背景图

如何将纯白色替换为背景图

3 回复

可以通过自定义tabBar的形式来做到。

demo如下:

// xxx.ets

import ComponentUtils from '[@ohos](/user/ohos).arkui.UIContext';

[@Entry](/user/Entry)

[@Component](/user/Component)

struct TabsExample {

[@State](/user/State) currentIndex: number = 0

[@State](/user/State) animationDuration: number = 300

[@State](/user/State) indicatorLeftMargin: number = 0

[@State](/user/State) indicatorWidth: number = 0

private tabsWidth: number = 0

private componentUtils: ComponentUtils.ComponentUtils = this.getUIContext().getComponentUtils()

[@Builder](/user/Builder)

tabBuilder(index: number, name: string) {

Column() {

Text(name)

.fontSize(16)

.fontColor(this.currentIndex === index ? '#007DFF' : '#182431')

.fontWeight(this.currentIndex === index ? 500 : 400)

.id(index.toString())

.onAreaChange((oldValue: Area,newValue: Area) => {

if (this.currentIndex === index && (this.indicatorLeftMargin === 0 || this.indicatorWidth === 0)){

if (newValue.position.x != undefined) {

let positionX = Number.parseFloat(newValue.position.x.toString())

this.indicatorLeftMargin = Number.isNaN(positionX) ? 0 : positionX

}

let width = Number.parseFloat(newValue.width.toString())

this.indicatorWidth = Number.isNaN(width) ? 0 : width

}

})

}.width('100%')

.backgroundImage($r('app.media.icon'))

.backgroundImageSize(ImageSize.Auto)

.backgroundImagePosition(Alignment.Center)

}

build() {

Stack({ alignContent: Alignment.TopStart }) {

Tabs({ barPosition: BarPosition.Start }) {

TabContent() {

Column().width('100%').height('100%').backgroundColor('#00CB87')

}.tabBar(this.tabBuilder(0, 'green'))

TabContent() {

Column().width('100%').height('100%').backgroundColor('#007DFF')

}.tabBar(this.tabBuilder(1, 'blue'))

TabContent() {

Column().width('100%').height('100%').backgroundColor('#FFBF00')

}.tabBar(this.tabBuilder(2, 'yellow'))

TabContent() {

Column().width('100%').height('100%').backgroundColor('#E67C92')

}.tabBar(this.tabBuilder(3, 'pink'))

}

.onAreaChange((oldValue: Area,newValue: Area)=> {

let width = Number.parseFloat(newValue.width.toString())

this.tabsWidth = Number.isNaN(width) ? 0 : width

})

.barWidth('100%')

.barHeight(56)

.width('100%')

.height(296)

.backgroundColor('#F1F3F5')

.animationDuration(this.animationDuration)

.onChange((index: number) => {

this.currentIndex = index // 监听索引index的变化,实现页签内容的切换。

})

.onAnimationStart((index: number, targetIndex: number, event: TabsAnimationEvent) => {

// 切换动画开始时触发该回调。下划线跟着页面一起滑动,同时宽度渐变。

this.currentIndex = targetIndex

let targetIndexInfo = this.getTextInfo(targetIndex)

this.startAnimateTo(this.animationDuration, targetIndexInfo.left, targetIndexInfo.width)

})

.onAnimationEnd((index: number,event: TabsAnimationEvent) => {

// 切换动画结束时触发该回调。下划线动画停止。

let currentIndicatorInfo = this.getCurrentIndicatorInfo(index,event)

this.startAnimateTo(0,currentIndicatorInfo.left,currentIndicatorInfo.width)

})

.onGestureSwipe((index: number,event: TabsAnimationEvent) => {

// 在页面跟手滑动过程中,逐帧触发该回调。

let currentIndicatorInfo = this.getCurrentIndicatorInfo(index,event)

this.currentIndex = currentIndicatorInfo.index

this.indicatorLeftMargin = currentIndicatorInfo.left

this.indicatorWidth = currentIndicatorInfo.width

})

Column()

.height(2)

.width(this.indicatorWidth)

.margin({ left: this.indicatorLeftMargin, top:48})

.backgroundColor('#007DFF')

}.width('100%')

}

private getTextInfo(index: number): Record<string, number> {

let rectangle = this.componentUtils.getRectangleById(index.toString())

return { 'left': px2vp(rectangle.windowOffset.x), 'width': px2vp(rectangle.size.width) }

}

private getCurrentIndicatorInfo(index: number, event: TabsAnimationEvent): Record<string, number> {

let nextIndex = index

if (index > 0 && event.currentOffset > 0) {

nextIndex--

} else if (index < 3 && event.currentOffset < 0) {

nextIndex++

}

let indexInfo = this.getTextInfo(index)

let nextIndexInfo = this.getTextInfo(nextIndex)

let swipeRatio = Math.abs(event.currentOffset / this.tabsWidth)

let currentIndex = swipeRatio > 0.5 ? nextIndex : index // 页面滑动超过一半,tabBar切换到下一页。

let currentLeft = indexInfo.left + (nextIndexInfo.left - indexInfo.left) * swipeRatio

let currentWidth = indexInfo.width + (nextIndexInfo.width - indexInfo.width) * swipeRatio

return { 'index': currentIndex, 'left': currentLeft, 'width': currentWidth }

}

private startAnimateTo(duration: number, leftMargin: number, width: number) {

animateTo({

duration: duration, // 动画时长

curve: Curve.Linear, // 动画曲线

iterations: 1, // 播放次数

playMode: PlayMode.Normal, // 动画模式

onFinish: () => {

console.info('play end')

}

}, () => {

this.indicatorLeftMargin = leftMargin

this.indicatorWidth = width

})

}

}

在HarmonyOS鸿蒙Next ArkUI中,为Tabs组件设置标签栏背景图,可以通过以下步骤实现:

  1. 准备背景图片:确保背景图片已正确放置在项目的资源目录中,并获取其路径。
  2. 创建Style对象:使用OHOS::UI::Style类创建一个Style对象,该类提供设置组件样式的功能。
  3. 加载背景图片:通过OHOS::UI::Image类加载背景图片,并将其设置为Style对象的背景。
  4. 应用Style到Tabs:将创建并设置好的Style对象应用到Tabs组件上,从而实现标签栏背景图的设置。

具体代码示例(使用C++语法):

#include <ohos.h>
using namespace OHOS::UI;

// 创建Style对象并加载背景图片
Style* style = new Style();
Image* background = Image::FromFile("path/to/your/background.png");
style->SetBackground(background);

// 获取Tabs组件并应用Style
Tabs* tabs = new Tabs();
tabs->SetStyle(style);

// 将Tabs添加到窗口中并显示
Window* window = new Window();
window->Add(tabs);
window->Show();

请注意将path/to/your/background.png替换为实际背景图片的路径。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部