首页 > 解决方案 > 如何不加载 ExpansionTile 的子项

问题描述

我有以下结构:扩展图块列表>单击它,打开另一个扩展图块列表>单击其中一个,它应该根据 SQL 查询打开一些小部件。

问题是,当我点击第一个扩展磁贴时,它会从第一个选项内的所有扩展磁贴中加载所有小部件,从而使查询非常慢。我只想在点击第二个小部件时加载小部件(仅加载必要的小部件)

这是代码:

class ListItemsScreen extends StatefulWidget {
  @override
  _ListItemsScreenState createState() => _ListItemsScreenState();
}
class _ListItemsScreenState extends State<ListItemsScreen> {

final Widget appBar = AppBar(
    title: Text('ITEMS'),
    actions: [
      Builder(
        builder: (context) => IconButton(
          icon: Icon(Icons.shopping_bag_outlined),
          onPressed: () {
            Navigator.of(context)
                .pushNamed(ROUTE_CHART);
          },
        ),
      ),
    ],
  );

@override
Widget build(BuildContext context) {
final List items = ModalRoute.of(context).settings.arguments;

return Scaffold(
        appBar: appBar,
        body: items == null || items.isEmpty ?
        Center(child: Text("0 items here"),)
            :
        ListView(
          children: [
            ...items.map<Widget>(
                  (item) {
                return ExpansionTile(
                    leading: Image.asset(ASSET_IMAGE,
                        fit: BoxFit.cover
                    ),
                    title: Text('${item.code}  |  ${item.description}'),
                    subtitle:
                    Text('${item.color}'),
                    children: [
                      Container(
                        height: MediaQuery.of(context).size.height,
                        width: MediaQuery.of(context).size.width,
                        child: ProductWidget(item),
                      ),
                    ],
                    ),

                );
              },
            )
          ],
        )
    );

class ProductWidget extends StatefulWidget {
  final Product product;

  ProductWidget(this.produto);

  @override
  _ProductWidgetState createState() => _ProductWidgetState();
}

class _ProdutoGradeWidgetState extends State<ProdutoGradeWidget> {
@override
Widget build(BuildContext context) {
CustomScrollView(
      slivers: [
        StreamBuilder(
          stream: product.stream,
          builder: (ctx, snapshot) {
              return SliverList(
                delegate: SliverChildBuilderDelegate((ctx, i) {
                  if (i == 0) {
                    return Column(
                      children: [
                        Align(
                            alignment: Alignment.center,
                            child: Padding(
                              padding: EdgeInsets.only(top: 5),
                              child: Text(
                                'I HAVE THIS PRODUCT IN THESE COLORS',
                                style: TextStyle(
                                  fontSize: 20,
                                  color:
                                  Theme.of(context).textTheme.caption.color,
                                ),
                              )
                            ),
                          ),
                        const SizedBox(height: 20.0),
                        ProductColorsWidget(color: snapshot.data[i]),
                      ],
                    );
                  } else if (i == snapshot.data.length - 1) {
                    return Column(
                      children: [
                        ProductColorsWidget(color: snapshot.data[i]),
                        const SizedBox(height: 20.0),
                        Padding(
                          padding: EdgeInsets.symmetric(horizontal: 20.0),
                          child: Align(
                            alignment: Alignment.centerLeft,
                            child: Text(
                              'Qtd',
                              style: TextStyle(
                                fontSize: 16,
                                color:
                                Theme.of(context).textTheme.caption.color,
                              ),
                            ),
                          ),
                        ),
                        const SizedBox(height: 20.0),
                      ],
                    );
                  }
                  return ProductColorsWidget(color: snapshot.data[i]);
                }, childCount: snapshot.data.length),
              );
            }
          },
        ),
      ],
    );
  }
}
}
}
class ProductColorsWidget extends StatelessWidget {
  final ColorProduct color;

  ProdutoCorGradeWidget({this.color});


@override
Widget build(BuildContext context) {
return ExpansionTile(
        maintainState: true,
        tilePadding: EdgeInsets.all(15.0),
        title: Text(
          '${color.id} - ${color.description}',
          style: Theme.of(context)
              .textTheme
              .subtitle1
              .copyWith(fontWeight: FontWeight.w600),
        ),
        childrenPadding: EdgeInsets.all(10.0),
        children: [
          Container(
              width: MediaQuery.of(context).size.width,
              height: MediaQuery.of(context).size.height,
              child: Row(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  ...color.sizes.map<Widget>(
                          (item) {
                        return Column(
                            children: [
                              Expanded(
                                  child: Text(
                                    item.description, textAlign: TextAlign.center,
                                    style: TextStyle(fontWeight: FontWeight.bold),
                                  )
                              ),
                              ...item.prices.map<Widget>((size) {
                                return PricesWidget( //here it should show the widgets according to the second ExpansionTiles
                                    color: color,
                                    size: size
                                );
                              })
                            ]
                        );
                      }
                  )
                ],
              )
          )
        ],

      );
  }
}

所以,要清楚,我想要的是:首先它列出了产品(带有expansionTiles),展开一个它应该显示第二个Tiles(带有大小),然后选择一个它应该显示小部件。

..但是现在发生的事情是:列出产品,当我选择一个时,应用程序会从所有第二个“expansionTiles”中加载所有小部件,从而导致显示第二个列表的速度变慢。我应该怎么办?

标签: flutterdartexpandablelistview

解决方案


我认为问题在于

ExpansionTile(
    maintainState: true,
    .....
)

我有一个类似的问题,其中我有一个 ExpansionTile 是它自己的孩子,它导致堆栈溢出,因为它正在构建它们。将维护状态设置为 false 后,问题就解决了。

您可能必须根据可能无法保存子状态来调整状态管理


推荐阅读