Flutter如何实现列表分组

在Flutter中如何实现类似通讯录那样的列表分组效果?比如按字母顺序将联系人分组,并在每组顶部显示字母标题。目前尝试使用ListView.builder但不知道如何动态添加分组标题,是否有现成的组件或最佳实践方案?希望了解具体实现方法和性能优化建议。

2 回复

Flutter中实现列表分组可使用ListView.builder结合groupBy对数据进行分组,或使用CustomScrollViewSliverList构建分组列表。也可使用第三方库如sticky_headers实现粘性分组头部。

更多关于Flutter如何实现列表分组的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中实现列表分组,可以使用以下几种方式:

1. ListView.builder + 条件判断

ListView.builder(
  itemCount: data.length,
  itemBuilder: (context, index) {
    // 如果是分组标题
    if (data[index].isHeader) {
      return Container(
        padding: EdgeInsets.all(16),
        color: Colors.grey[200],
        child: Text(
          data[index].title,
          style: TextStyle(fontWeight: FontWeight.bold),
        ),
      );
    }
    // 如果是列表项
    return ListTile(
      title: Text(data[index].title),
    );
  },
)

2. 使用 grouped_list 包(推荐)

首先添加依赖:

dependencies:
  grouped_list: ^5.1.2

使用示例:

GroupedListView<dynamic, String>(
  elements: yourDataList,
  groupBy: (element) => element.group,
  groupComparator: (value1, value2) => value2.compareTo(value1),
  itemComparator: (item1, item2) => item1.name.compareTo(item2.name),
  order: GroupedListOrder.DESC,
  useStickyGroupSeparators: true,
  groupSeparatorBuilder: (String value) => Padding(
    padding: const EdgeInsets.all(8.0),
    child: Text(
      value,
      style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
    ),
  ),
  itemBuilder: (c, element) {
    return Card(
      child: ListTile(
        title: Text(element.name),
        subtitle: Text(element.group),
      ),
    );
  },
)

3. 自定义实现

class GroupedListView extends StatelessWidget {
  final Map<String, List<dynamic>> groupedData;
  
  Widget build(BuildContext context) {
    return ListView(
      children: groupedData.entries.map((entry) {
        return Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // 分组标题
            Container(
              padding: EdgeInsets.all(16),
              color: Colors.grey[300],
              child: Text(
                entry.key,
                style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
              ),
            ),
            // 分组内容
            ...entry.value.map((item) => ListTile(
              title: Text(item.name),
            )).toList(),
          ],
        );
      }).toList(),
    );
  }
}

推荐使用 grouped_list 包,它提供了更好的性能和更丰富的功能,如粘性头部、自定义排序等。

回到顶部