Read the original article:How to display only the corresponding TabContent page?
How to display only the corresponding TabContent page?
Problem Description
In the Tabs component, since it comes with a built-in sliding animation for switching between pages, when you click on a tab bar to switch pages, the current page will slide to the target page. This causes the intermediate pages between the current and target pages to be loaded as well.
Background Knowledge
LazyForEach must be used within container components. Only the List, ListItemGroup, Grid, Swiper, and WaterFlow components support lazy data loading. Other components still load all data at once. Refer to the usage restrictions for details.
To customize the animation for tab page switching, refer to the usage of customContentTransition.
Solution
Option 1: Since the Tabs component comes with a built-in sliding transition animation for page switching, when you click on a tab bar to switch pages, the current page will slide to the target page, causing intermediate pages between the current and target pages to be loaded as well. You can use custom transition animations to avoid the default animation provided by the Tabs component. Refer to the customContentTransition usage instructions.
Example code is as follows:
@Entry
@Component
struct TabsDemo {
@State currentIndex: number = 0
private tabsController: TabsController = new TabsController()
private customContentTransition: (from: number, to: number) => TabContentAnimatedTransition =
(from: number, to: number) => {
let tabContentAnimatedTransition = {
timeout: 1000,
transition: (proxy: TabContentTransitionProxy) => {
this.getUIContext().animateTo({
duration: 0,
onFinish: () => {
proxy.finishTransition()
}
}, () => {
})
}
} as TabContentAnimatedTransition
return tabContentAnimatedTransition
}
build() {
Column() {
Tabs({ index: this.currentIndex, controller: this.tabsController }) {
TabContent() {
MyComponent({ color: '#00CB87' })
}.tabBar(SubTabBarStyle.of('green'))
TabContent() {
MyComponent({ color: '#007DFF' })
}.tabBar(SubTabBarStyle.of('blue'))
TabContent() {
MyComponent({ color: '#FFBF00' })
}.tabBar(SubTabBarStyle.of('yellow'))
TabContent() {
MyComponent({ color: '#E67C92' })
}.tabBar(SubTabBarStyle.of('pink'))
}
.customContentTransition(this.customContentTransition)
.width('100%')
.height(296)
.onChange((index: number) => {
this.currentIndex = index
})
}
}
}
@Component
struct MyComponent {
private color: string = ""
aboutToAppear(): void {
console.info('------aboutToAppear backgroundColor:' + this.color)
}
aboutToDisappear(): void {
console.info('------aboutToDisappear backgroundColor:' + this.color)
}
build() {
Column() {
Text(this.color)
.width('90%')
.height(200)
.borderRadius(10)
.backgroundColor($r('sys.color.comp_background_focus'))
.textAlign(TextAlign.Center)
.fontSize(30)
}
}
}
The run log is as follows, which can prevent intermediate tabs from being loaded:
08-13 10:25:53.034 22832-22832 A03d00/JSAPP com.example.ir_test I ------aboutToAppear backgroundColor:#00CB87
08-13 10:26:04.021 22832-22832 A03d00/JSAPP com.example.ir_test I ------aboutToAppear backgroundColor:#E67C92
08-13 10:26:05.250 22832-22832 A03d00/JSAPP com.example.ir_test I ------aboutToAppear backgroundColor:#FFBF00
Option 2 : To avoid loading intermediate pages while retaining the swipe gesture for switching between pages, you can use Swiper to customize the Tabs component. By calling the changeIndex method of SwiperController to navigate to a specified page, you can set useAnimation to false to disable animations.
Example code is as follows:
class MyDataSource implements IDataSource {
private list: number[] = []
constructor(list: number[]) {
this.list = list
}
totalCount(): number {
return this.list.length
}
getData(index: number): number {
return this.list[index]
}
registerDataChangeListener(listener: DataChangeListener): void {
}
unregisterDataChangeListener() {
}
}
@Entry
@Component
struct SwiperExample {
private swiperController: SwiperController = new SwiperController()
private data: MyDataSource = new MyDataSource([])
aboutToAppear(): void {
let list: number[] = []
for (let i = 1; i <= 10; i++) {
list.push(i);
}
this.data = new MyDataSource(list)
}
build() {
Column({ space: 5 }) {
Swiper(this.swiperController) {
LazyForEach(this.data, (item: string) => {
Text(item.toString())
.width('90%')
.height(160)
.borderRadius(10)
.backgroundColor($r('sys.color.comp_background_focus'))
.textAlign(TextAlign.Center)
.fontSize(30)
}, (item: string) => item)
}
.cachedCount(2)
.index(1)
.autoPlay(true)
.interval(4000)
.loop(true)
.duration(1000)
.itemSpace(0)
.indicator(false)
Row({ space: 12 }) {
Button('change to index:4')
.onClick(() => {
this.swiperController.changeIndex(3,false)
})
Button('change to index:7')
.onClick(() => {
this.swiperController.changeIndex(6,false)
})
}.margin(5)
}.width('100%')
.margin({ top: 5 })
}
}
Verification Result
After disabling the default tab sliding animation using customContentTransition or replacing Tabs with a Swiper and setting useAnimation to false, only the corresponding TabContent page is displayed and loaded, and intermediate pages are no longer created or rendered during tab switching.
Top comments (0)