管理中心
我的
您当前正在浏览新版开发者文档中心,目录分类和层级有所调整。点击左侧当前文档分类名称前的“☰”图标,可切换文档分类。 了解新版目录
问题处理与运维开发与测试问题应用框架开发UI框架组件使用Tabs如何实现预加载特定的TabContent页

Tabs如何实现预加载特定的TabContent页

方案一:不论用ForEach还是LazyForEach循环渲染TabContent里面的内容都是一次渲染,故不能使用循环渲染。

由于Tabs组件自带滑动切换页面动画,所以在点击TabBar切换页面时会从当前页面滑动到目标页面,导致当前页面和目标页面的中间页面也被加载。可以使用自定义切换动画去规避Tabs组件自带的动画导致多个TabContent加载的问题。参考customContentTransition使用说明。

参考代码:

收起
自动换行
深色代码主题
复制
  1. @Entry
  2. @Component
  3. struct TabsDemo {
  4. @State currentIndex: number = 0;
  5. private tabsController: TabsController = new TabsController();
  6. // Set up page switching animations instead of sliding to jump to page animations
  7. private customContentTransition: (from: number, to: number) => TabContentAnimatedTransition =
  8. (from: number, to: number) => {
  9. let tabContentAnimatedTransition = {
  10. timeout: 1000,
  11. transition: (proxy: TabContentTransitionProxy) => {
  12. this.getUIContext().animateTo({
  13. duration: 0,
  14. onFinish: () => {
  15. proxy.finishTransition();
  16. }
  17. }, () => {
  18. })
  19. }
  20. } as TabContentAnimatedTransition
  21. return tabContentAnimatedTransition;
  22. }
  23. build() {
  24. Column() {
  25. Tabs({ index: this.currentIndex, controller: this.tabsController }) {
  26. TabContent() {
  27. MyComponent({ color: '#00CB87' })
  28. }.tabBar(SubTabBarStyle.of('green'))
  29. TabContent() {
  30. MyComponent({ color: '#007DFF' })
  31. }.tabBar(SubTabBarStyle.of('green'))
  32. TabContent() {
  33. MyComponent({ color: '#FFBF00' })
  34. }.tabBar(SubTabBarStyle.of('green'))
  35. TabContent() {
  36. MyComponent({ color: '#E67C92' })
  37. }.tabBar(SubTabBarStyle.of('green'))
  38. }
  39. .customContentTransition(this.customContentTransition)
  40. .width('100%')
  41. .height(296)
  42. .barBackgroundColor('#F1F3F5')
  43. .onChange((index: number) => {
  44. this.currentIndex = index;
  45. })
  46. }
  47. }
  48. }
  49. @Component
  50. struct MyComponent {
  51. private color: string = '';
  52. aboutToAppear(): void {
  53. // It can be observed by printing the log that no intermediate page has been loaded
  54. console.info('aboutToAppear backgroundColor:' + this.color);
  55. }
  56. aboutToDisappear(): void {
  57. console.info('aboutToDisappear backgroundColor:' + this.color);
  58. }
  59. build() {
  60. Column()
  61. .width('100%')
  62. .height('100%')
  63. .backgroundColor(this.color)
  64. }
  65. }

方案二:若要同时规避加载中间页面,又要保留手势滑动切换页面功能,可以使用Swiper自定义实现Tabs组件。通过调用SwiperController的changeIndex方法翻至指定页面,useAnimation设置为false时没有动效。

参考代码:

收起
自动换行
深色代码主题
复制
  1. class MyDataSource implements IDataSource {
  2. private list: number[] = [];
  3. constructor(list: number[]) {
  4. this.list = list;
  5. }
  6. totalCount(): number {
  7. return this.list.length;
  8. }
  9. getData(index: number): number {
  10. return this.list[index];
  11. }
  12. registerDataChangeListener(listener: DataChangeListener): void {
  13. }
  14. unregisterDataChangeListener(listener: DataChangeListener): void {
  15. }
  16. }
  17. @Entry
  18. @Component
  19. struct SwiperExample {
  20. private swiperController: SwiperController = new SwiperController();
  21. private data: MyDataSource = new MyDataSource([]);
  22. aboutToAppear(): void {
  23. let list: number[] = [];
  24. for (let i = 0; i <= 10; i++) {
  25. list.push(i);
  26. }
  27. this.data = new MyDataSource(list);
  28. }
  29. build() {
  30. Column({ space: 5 }) {
  31. Swiper(this.swiperController) {
  32. LazyForEach(this.data, (item: string) => {
  33. Text(item.toString())
  34. .width('90%')
  35. .height(160)
  36. .backgroundColor(0XAFEEEE)
  37. .textAlign(TextAlign.Center)
  38. .fontSize(30)
  39. }, (item: string) => item)
  40. }
  41. .cachedCount(2)
  42. .index(1)
  43. .autoPlay(true)
  44. .interval(4000)
  45. .loop(true)
  46. .duration(1000)
  47. .itemSpace(0)
  48. .indicator(false)
  49. Row({ space: 12 }) {
  50. Button('change to index:4')
  51. .onClick(() => {
  52. this.swiperController.changeIndex(3, false);
  53. })
  54. Button('change to index:7')
  55. .onClick(() => {
  56. this.swiperController.changeIndex(6, false);
  57. })
  58. }
  59. .margin(5)
  60. }
  61. .width('100%')
  62. .margin({ top: 5 })
  63. }
  64. }