【HarmonyOS开发】ArkTs实现侧栏联动

发布时间:2023年12月19日

图片

侧栏联动功能模块:????

????1、切换左侧导航,右侧滚动到对应的内容。????

????2、滚动右侧的内容,左侧会切换对应的导航。

1、涉及知识点

List(列表组件)、ListItemGroup(列表item分组)

2、效果预览

图片

3、实现思路

????整体UI处理:左右两侧均为List组件,一层树状数据,左侧取顶层数据,右侧取一层数据,并使用ListItemGroup对List进行分组处理。

? ? 1、左侧点击:通过Scroll组件的 scrollToIndex 方法滚动到对应的位置;

? ? 2、右侧滚动左侧跟随:通过?onScrollIndex? 监听滚动的Index位置;

// onScrollIndex监听和左侧点击scrollIndexChangeAction(index: number, isClassify: boolean) {  if (this.currentIndex !== index) {????//?改变状态.    this.currentIndex = index;    if (isClassify) {      //滚动      this.scroller.scrollToIndex(index);    } else {      // 判断左侧滚动还是右侧滚动      this.sidebarScroller.scrollToIndex(index);    }  }}

4、组件封装和调用

????4.1?组件封装

??

@Component
export struct SidebarItem {
  @Prop isSelected: boolean = false;
  classifyName?: string;
  onClickAction = () => {}

  build() {
    Text(this.classifyName)
      .fontSize(14)
      .fontColor(this.isSelected ? '#182431' : '#99182431')
      .fontFamily(this.isSelected ? 'HarmonyHeiTi-Medium' : 'HarmonyHeiTi')
      .fontWeight(this.isSelected ? 500 : 400)
      .textAlign(TextAlign.Center)
      .backgroundColor(this.isSelected ? '#F1F3F5' : '')
      .width('100%')
      .height(56)
      .onClick(this.onClickAction)
  }
}

@Component
export default struct SidebarLinkage {
  @BuilderParam CourseItem: (item) => void;
  @Prop dataList: Array<any> = [];
  @Prop requestSuccess: boolean = false;

  @State currentIndex: number = 0; // selected classify index.
  private sidebarScroller: Scroller = new Scroller();
  private scroller: Scroller = new Scroller();

  @Builder blcokHeader(classifyName: string) {
    Row() {
      Text(classifyName)
        .fontSize(18)
        .fontColor('#182431')
        .fontFamily('HarmonyHeiTi-Medium')
        .fontWeight(500)
    }
    .padding({ left: 8 })
    .height(56)
    .width('100%')
    .backgroundColor('#F1F3F5')
  }

  scrollIndexChangeAction(index: number, isClassify: boolean) {
    if (this.currentIndex !== index) {
      // change the classify status.
      this.currentIndex = index;
      if (isClassify) {
        // scroll the course scroll.
        this.scroller.scrollToIndex(index);
      } else {
        // scroll the classify scroll.
        this.sidebarScroller.scrollToIndex(index);
      }
    }
  }

  build() {
    Row() {
      if (this.requestSuccess) {
        List({ scroller: this.sidebarScroller }) {
          ForEach(this.dataList, (item: any, index?: number) => {
            ListItem() {
              SidebarItem({
                classifyName: item.classifyName,
                isSelected: this.currentIndex === index,
                onClickAction: () => {
                  if (index !== undefined) {
                    this.scrollIndexChangeAction(index, true);
                  }
                }
              })
            }
          }, (item: any) => item.classifyName + this.currentIndex)
        }
        .height('100%')
        .width(100)
        .backgroundColor('#0D182431')
        .scrollBar(BarState.Off)

        List({ scroller: this.scroller }) {
          ForEach(this.dataList, (item: any) => {
            ListItemGroup({
              header: this.blcokHeader(item.classifyName),
              space: 12
            }) {
              ForEach(item.courseList, (courseItem: any) => {
                ListItem() {
                  this.CourseItem({ itemStr: JSON.stringify(courseItem) })
                }
              }, (courseItem: any) => `${courseItem.courseId}`)
            }
          }, (item: any) => `${item.classifyId}`)
        }
        .padding({ left: 8, right: 12 })
        .sticky(StickyStyle.Header)
        .layoutWeight(1)
        .edgeEffect(EdgeEffect.None)
        .onScrollIndex((start: number) => this.scrollIndexChangeAction(start, false))
      } else {
        Text('loading...')
          .fontFamily('HarmonyHeiTi-Medium')
          .textAlign(TextAlign.Center)
          .fontSize(18)
          .height('100%')
          .width('100%')
      }
    }
    .backgroundColor('#F1F3F5')
  }
}

????4.2 组件调用

import SidebarLinkage from '../../../../../SidebarLinkage/src/main/ets/components/SidebarLinkage/SidebarLinkage'

@Entry
@Component
struct IndexPage {
  @State requestSuccess: boolean = false; // is loading data.
  @State classifyList: Array<any> = [];

  aboutToAppear() {
    // loading data.
    setTimeout(() => {
      this.classifyList = [
        { "classifyId": 1, "classifyName": "音乐",
          "courseList": [{
            "classifyId": 0,
            "courseId": 1,
            "courseName": "YouTube1",
            "imageUrl": $r('app.media.youtube'),
            "price": 0
          },{
            "classifyId": 1,
            "courseId": 2,
            "courseName": "YouTube2",
            "imageUrl": $r('app.media.youtube'),
            "price": 12
          },{
            "classifyId": 1,
            "courseId": 3,
            "courseName": "YouTube3",
            "imageUrl": $r('app.media.youtube'),
            "price": 22
          },{
            "classifyId": 1,
            "courseId": 4,
            "courseName": "YouTube4",
            "imageUrl": $r('app.media.youtube'),
            "price": 43
          },{
            "classifyId": 1,
            "courseId": 5,
            "courseName": "YouTube5",
            "imageUrl": $r('app.media.youtube'),
            "price": 430
          },{
            "classifyId": 1,
            "courseId": 6,
            "courseName": "YouTube6",
            "imageUrl": $r('app.media.youtube'),
            "price": 120
          }]
        },
        { "classifyId": 2, "classifyName": "游戏",
          "courseList": [{
            "classifyId": 2,
            "courseId": 1,
            "courseName": "Twitter1",
            "imageUrl": $r('app.media.twitter'),
            "price": 797970
          },{
            "classifyId": 2,
            "courseId": 2,
            "courseName": "Twitter2",
            "imageUrl": $r('app.media.twitter'),
            "price": 98790
          },{
            "classifyId": 2,
            "courseId": 3,
            "courseName": "Twitter3",
            "imageUrl": $r('app.media.twitter'),
            "price": 7337
          },{
            "classifyId": 2,
            "courseId": 4,
            "courseName": "Twitter4",
            "imageUrl": $r('app.media.twitter'),
            "price": 33330
          },{
            "classifyId": 2,
            "courseId": 5,
            "courseName": "Twitter5",
            "imageUrl": $r('app.media.twitter'),
            "price": 7770
          },{
            "classifyId": 2,
            "courseId": 6,
            "courseName": "Twitter6",
            "imageUrl": $r('app.media.twitter'),
            "price": 30
          }]
        },
        { "classifyId": 3, "classifyName": "旅游",
          "courseList": [{
            "classifyId": 3,
            "courseId": 1,
            "courseName": "whatsapp1",
            "imageUrl": $r('app.media.whatsapp'),
            "price": 6330
          },{
            "classifyId": 3,
            "courseId": 2,
            "courseName": "whatsapp2",
            "imageUrl": $r('app.media.whatsapp'),
            "price": 730
          },{
            "classifyId": 3,
            "courseId": 3,
            "courseName": "whatsapp3",
            "imageUrl": $r('app.media.whatsapp'),
            "price": 330
          },{
            "classifyId": 3,
            "courseId": 4,
            "courseName": "whatsapp4",
            "imageUrl": $r('app.media.whatsapp'),
            "price": 730
          },{
            "classifyId": 3,
            "courseId": 5,
            "courseName": "whatsapp5",
            "imageUrl": $r('app.media.whatsapp'),
            "price": 0
          },{
            "classifyId": 3,
            "courseId": 6,
            "courseName": "whatsapp6",
            "imageUrl": $r('app.media.whatsapp'),
            "price": 0
          },{
            "classifyId": 3,
            "courseId": 7,
            "courseName": "whatsapp7",
            "imageUrl": $r('app.media.whatsapp'),
            "price": 70
          },{
            "classifyId": 3,
            "courseId": 8,
            "courseName": "whatsapp8",
            "imageUrl": $r('app.media.whatsapp'),
            "price": 60
          },{
            "classifyId": 3,
            "courseId": 9,
            "courseName": "whatsapp9",
            "imageUrl": $r('app.media.whatsapp'),
            "price": 40
          },{
            "classifyId": 3,
            "courseId": 10,
            "courseName": "whatsapp10",
            "imageUrl": $r('app.media.whatsapp'),
            "price": 20
          },{
            "classifyId": 3,
            "courseId": 11,
            "courseName": "whatsapp11",
            "imageUrl": $r('app.media.whatsapp'),
            "price": 0
          }]
        }
      ];
      this.requestSuccess = true;
    }, 2000);
  }

  @Builder CourseItemBuilder(item: any) {
    Row() {
      Image(JSON.parse(item.itemStr) !== undefined ? JSON.parse(item.itemStr)?.imageUrl : '')
        .height('100%')
        .aspectRatio(1)
      Column() {
        Text(JSON.parse(item.itemStr)?.courseName)
          .fontSize(14)
          .fontColor('#182431')
          .fontFamily('HarmonyHeiTi-Medium')
          .maxLines(2)
          .textOverflow({ overflow: TextOverflow.Clip })
          .lineHeight(20)
          .width('100%')
        Text('$ 999.99')
          .fontSize(16)
          .fontColor(Color.Pink)
          .fontFamily('HarmonyHeiTi-Medium')
        Text(JSON.parse(item.itemStr)?.price === 0 ? '免费' : `$${JSON.parse(item.itemStr)?.price}`)
          .fontSize(18)
          .fontColor('#FA2A2D')
          .fontFamily('HarmonyHeiTi-Medium')
      }
      .padding(12)
      .layoutWeight(1)
      .alignItems(HorizontalAlign.Start)
      .justifyContent(FlexAlign.SpaceBetween)
      .height('100%')
    }
    .clip(true)
    .borderRadius(18)
    .backgroundColor($r('app.color.start_window_background'))
    .width('100%')
    .height(96)
  }

  build() {
    Column() {
      SidebarLinkage({
        dataList: this.classifyList,
        requestSuccess: this.requestSuccess,
        CourseItem: this.CourseItemBuilder
      })
    }
  }
}

图片

源码:https://gitee.com/bingtengaoyu/harmonyos-advanced-componen/tree/master/SidebarLinkage?

文章来源:https://blog.csdn.net/qq_23334071/article/details/135084597
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。