# 如何实现List组件在多列模式下特殊列表项的独立布局

#### 问题现象

在List组件中使用lanes属性进行约束时，List组件会根据滚动方向设置为多列或多行显示。List组件内如何实现特殊的item，不受lanes影响，始终保持单行或单列显示。

#### 效果预览

#### 背景知识

*   List：用于展示动态数据集合的核心组件，支持滚动、动态更新等特性。可以利用lanes设置List组件的布局列数或行数。
*   ListItemGroup：该组件用来展示列表item分组，宽度默认充满List组件，必须配合List组件来使用。用于分组管理列表项及其附属元素。

#### 解决方案

1.  使用ForEach循环渲染数据列表，但只渲染type为normal的普通项，每个普通项采用标准卡片式设计。
2.  通过if条件渲染插入ListItemGroup特殊项来实现布局逻辑的分离，确保列表结构的完整性。
3.  由于ListItemGroup的footer和header不会受lanes属性影响，同时lanes属性会自动计算布局空间，确保组件自适应屏幕尺寸。
    
    ```
    interface Item {
      id: number,
      type: string,
      text: string
    }
    
    class FootBuilderParams {
      num: number | Resource;
    
      constructor(num: number | Resource) {
        this.num = num;
      }
    }
    
    @Builder
    function itemFoot() {
    
      Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center }) {
        Text('我是独立居中项')
          .fontSize(18)
          .fontColor('#FFFFFF')
          .padding(20)
          .backgroundColor('#FF007DFF')
          .borderRadius(12);
      };
    }
    
    interface TimeTable {
      title: string;
      projects: string[];
    }
    
    @Preview
    @Entry
    @Component
    struct SpecialListLayout {
      // 模拟数据
      @State dataList: Item[] = [
        { id: 1, type: 'normal', text: '普通项1' },
        { id: 2, type: 'normal', text: '普通项2' },
        { id: 3, type: 'special', text: '独立居中项' }, // 特殊居中项
        { id: 4, type: 'normal', text: '普通项3' },
        { id: 5, type: 'normal', text: '普通项4' },
        { id: 6, type: 'normal', text: '普通项6' }
      ];
      item: TimeTable = { title: '', projects: [] };
      footer?: ComponentContent<FootBuilderParams> = undefined;
      footerParam = new FootBuilderParams(this.item.projects.length);
    
      build() {
        List({ space: 10 }) {
          // 普通双列项
          ForEach(this.dataList, (item: Item) => {
            // 只渲染普通项（过滤特殊项）
            if (item.type === 'normal') {
              ListItem() {
                Text(item.text)
                  .fontSize(16)
                  .backgroundColor('#F0F0F0')
                  .padding(10)
                  .borderRadius(8);
              }
              .width('100%'); // 关键：让普通项参与双列布局
            }
          });
          // 特殊居中项（独立处理）
          ListItemGroup({ footer: itemFoot() }) {
            ListItem() {
            };
          };
        }
        .lanes(2) // 全局双列布局
        .alignListItem(ListItemAlign.Start)
        .backgroundColor('#FFFFFF');
      }
    }
    ```
    

#### 常见FAQ

Q：List是否支持设置不同的lanes属性，如设置占1列的标题和占4列的内容。

A：List的lanes属性，暂不支持对单独某行或某列进行设置，实现上述效果，可通过多个List组合实现。

#### 总结

在使用List组件进行类似布局会有诸多限制，特殊项的布局位置也不灵活，建议使用Grid组件是网格容器，其布局由行和列组成，可以通过设置layoutOptions参数，指定单元格做出不同的布局。