You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter分类页面ExpansionTile无法展开问题求助

问题排查与修复方案

核心问题1:FirestoreListView导致ExpansionTile状态丢失

你在MainCategoryWidget中使用的FirestoreListView是基于Firebase实时数据流的列表组件,每次父组件(比如左侧分类切换触发setState)或Firestore数据更新时,会重新构建所有列表项,导致ExpansionTile的展开状态被重置,点击后无法保持展开状态,看起来像是无法展开。

修复方法:替换FirestoreListView为FirestoreQueryBuilder+ListView.builder

手动构建列表,避免自动重建所有列表项,同时保持数据流监听:

class MainCategoryWidget extends StatefulWidget {
  final String? selectedCat;
  const MainCategoryWidget({this.selectedCat, Key? key}) : super(key: key);

  @override
  State<MainCategoryWidget> createState() => _MainCategoryWidgetState();
}

class _MainCategoryWidgetState extends State<MainCategoryWidget> {
  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: FirestoreQueryBuilder<MainCategory>(
        query: mainCategoryCollection(widget.selectedCat),
        builder: (context, snapshot, _) {
          if (snapshot.isFetching) {
            return const Center(child: CircularProgressIndicator());
          }
          if (snapshot.hasError) {
            return Text('加载失败:${snapshot.error}');
          }
          if (snapshot.docs.isEmpty) {
            return const Center(child: Text('暂无分类数据'));
          }
          return ListView.builder(
            itemCount: snapshot.docs.length,
            itemBuilder: (context, index) {
              MainCategory mainCategory = snapshot.docs[index].data();
              // 给ExpansionTile添加唯一key,确保状态不丢失
              return ExpansionTile(
                key: ValueKey(mainCategory.mainCategory),
                title: Text(mainCategory.mainCategory!),
                children: [
                  SubCategoryWidget(
                    selectedSubCat: mainCategory.mainCategory,
                  )
                ],
              );
            },
          );
        },
      ),
    );
  }
}

核心问题2:SubCategoryWidget中的Expanded导致布局冲突

SubCategoryWidget作为ExpansionTile的子组件,内部使用了Expanded,但ExpansionTile的子组件不需要额外的Expanded(因为父级已经是可滚动的ListView),这会导致布局约束冲突,影响ExpansionTile的展开动画和交互。

修复方法:移除SubCategoryWidget中的Expanded

class SubCategoryWidget extends StatelessWidget {
  final String? selectedSubCat;
  const SubCategoryWidget({this.selectedSubCat, Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // 移除外层的Expanded
    return FirestoreQueryBuilder<SubCategory>(
      query: subCategoryCollection(
        selectedSubCat: selectedSubCat
      ),
      builder: (context, snapshot, _) {
        if (snapshot.isFetching) {
          return const Center(child: CircularProgressIndicator());
        }
        if (snapshot.hasError) {
          return Text('加载失败:${snapshot.error}');
        }
        return GridView.builder(
          shrinkWrap: true,
          // 添加禁止内部滚动的属性,避免与外部ListView冲突
          physics: const NeverScrollableScrollPhysics(),
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
            childAspectRatio: 1/1.1,
          ),
          itemCount: snapshot.docs.length,
          itemBuilder: (context, index) {
            SubCategory subCat = snapshot.docs[index].data();
            return InkWell(
              onTap: (){
                // 跳转到产品页面
              },
              child: Column(
                children: [
                  SizedBox(
                    height: 60,
                    width: 60,
                    child: FittedBox(
                      fit: BoxFit.contain,
                      child: Image.network(subCat.image!)),
                  ),
                  Text(subCat.subCatName!,style: const TextStyle(fontSize: 12),
                    textAlign: TextAlign.center,
                  ),
                ],
              ),
            );
          },
        );
      },
    );
  }
}

额外优化:处理初始无选中分类的情况

当selectedCategory为null时,mainCategoryCollection的查询会寻找category等于null的文档,大概率没有数据。可以在CategoryScreen中设置默认选中第一个分类,或者保持现有逻辑,通过上述修复中的空状态提示告知用户。


内容的提问来源于stack exchange,提问作者Henrique Crusoe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 06:35:48