HarmonyOS NEXT实现类似ExpandList,可折叠打开的list组件?

阅读 520
avatarAI BotBETA
**回答**:
HarmonyOS NEXT 提供了丰富的组件库,虽然没有直接命名为 `ExpandList` 的组件,但你可以通过使用 `ListContainer` 和 `SwipeRefresh` 等组件结合自定义逻辑来实现类似可折叠打开的列表效果。你可以通过控制子项的显示与隐藏来实现列表项的展开与折叠功能。

具体实现思路如下:
1. 使用 `ListContainer` 作为外层列表容器。
2. 每个列表项内可以包含一个用于触发展开/折叠操作的按钮或其他控件。
3. 根据按钮的点击事件,动态控制子项(即折叠内容)的显示与隐藏。

此外,你还可以利用数据绑定和事件处理机制来简化这一实现过程。

请注意,具体实现细节可能需要根据你的具体需求和UI设计进行调整。
1 个回答

具体参考代码:

interface IRowItem { 
  id?: number; 
  title?: string; 
  name1?: string; 
  name2?: string; 
  name3?: string; 
  flag?: boolean; 
  type?: string; 
  onFlagChange?: () => void; 
} 
 
@Entry 
@Component 
struct CollapseAndExpandDemo { 
  @Provide("flag") flag: boolean = false 
  private onFlagChange = () => { 
    animateTo({ 
      duration: 650, 
      curve: Curve.Smooth 
    }, () => { 
      this.flag = !this.flag; 
    }) 
  } 
 
  build() { 
    Column() { 
      Row() { 
        Image($r("app.media.ic_public_back")).width(20).height(20) 
        Text('标题').fontSize(18).fontWeight(FontWeight.Bold).margin({ left: 10 }) 
      }.width('100%').margin({ bottom: 30 }) 
 
      Column() { 
        RowItem({ props: { title: '全部类型', name1: '言情小说', name2: '推理悬疑', name3: '情感家庭' } }) 
        RowItem({ 
          props: { name1: '幻想小说', name2: '惊悚/恐怖', name3: '武侠小说', type: 'DOWN', onFlagChange: this.onFlagChange 
          } 
        }) 
        // 直接调用折叠展开组件 
        CollapseAndExpand({ 
          items: [ 
            { id: 0, name1: '科幻小说', name2: '官场', name3: '历史/架空' }, 
            { id: 1, name1: '职场商战', name2: '军事谍战', name3: '世界名著' }, 
            { id: 2, name1: '社会小说', name2: '乡土小说', name3: '中国近当代' }, 
            { id: 3, name1: '中国古典', name2: '外国小说', name3: '小说作品集', type: 'UP', onFlagChange: this.onFlagChange } 
          ], 
        }) 
 
        RowItem({ props: { title: '全部价格', name1: '免费', name2: '特价', name3: 'VIP' } }) 
        RowItem({ props: { title: '按人气', name1: '按最新', name2: '按收藏', name3: '按字数' } }) 
      }.width('100%') 
 
    } 
    .height('100%') 
    .padding({ top: 30, right: 30, left: 30 }) 
  } 
} 
 
@Component 
struct RowItem { 
  private props: IRowItem; 
  @Consume("flag") flag: boolean 
  build() { 
    Flex() { 
      Text(this.props.title) 
        .fontSize(14) 
        .fontWeight(FontWeight.Bold) 
        .layoutWeight(1) 
        .fontColor(Color.Red) 
        .margin({ right: 10 }) 
      Flex({ alignItems: ItemAlign.Center }) { 
        Text(this.props.name1).fontSize(14).margin({ right: 10 }) 
        Text(this.props.name2).fontSize(14).margin({ right: 10 }) 
        Text(this.props.name3).fontSize(14).margin({ right: 10 }) 
 
        if (!this.flag && this.props.type === 'DOWN' || this.flag && this.props.type === 'UP') { 
          Image($r("app.media.ic_public_arrow_down_0")) 
            .width(16) 
            .height(16) 
            .objectFit(ImageFit.Contain) 
            .rotate({ angle: !this.flag && this.props.type === 'DOWN' ? 0 : 180 }) // 点击展开按钮后旋转180°,展示折叠按钮 
            .onClick(() => this.props.onFlagChange()) 
            .transition({ type: TransitionType.All, opacity: 0 }) 
        } 
      } 
      .layoutWeight(3) 
    }.width('100%').height(16).margin({ top: 15 }) 
  } 
} 
 
@Component 
struct CollapseAndExpand { 
  private items: IRowItem[] = []; 
  @Consume("flag") flag: boolean; 
 
  build() { 
    Column() { 
      ForEach(this.items, (item: IRowItem) => { 
        RowItem({ props: item }) 
      }, (item: IRowItem) => item.id.toString()) 
    } 
    .width('100%') 
    .clip(true) 
    .height(this.flag ? 130 : 0) 
  } 
}

本文参与了 【 HarmonyOS NEXT 技术问答冲榜,等你来战!】欢迎正在阅读的你也加入。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进