【问题标题】:How to rebuild all grid items in flutter?如何重建颤振中的所有网格项目?
【发布时间】:2019-08-27 13:45:32
【问题描述】:

我有一个 dashboard,由网格表示,它应该在长按事件时删除项目(使用 flutter_bloc),但它会删除最后一个项目而不是选中的项目。所有调试打印都显示,需要的元素实际上已从列表中删除,但视图层仍保留它。

我的构建函数代码:

  Widget build(BuildContext context) {
    double pyxelRatio = MediaQuery.of(context).devicePixelRatio;
    double width = MediaQuery.of(context).size.width * pyxelRatio;

    return BlocProvider(
      bloc: _bloc,
        child: BlocBuilder<Request, DataState>(
        bloc: _bloc,
        builder: (context, state) {
          if (state is EmptyDataState) {
            print("Uninit");
            return Center(
              child: CircularProgressIndicator(),
            );
          }
          if (state is ErrorDataState) {
            print("Error");
            return Center(
              child: Text('Something went wrong..'),
            );
          }
          if (state is LoadedDataState) {
            print("empty: ${state.contracts.isEmpty}");
            if (state.contracts.isEmpty) {
              return Center(
                child: Text('Nothing here!'),
              );
            } else{
              print("items count: ${state.contracts.length}");              
              print("-------");
              for(int i = 0; i < state.contracts.length; i++){
                if(state.contracts[i].isFavorite)print("fut:${state.contracts[i].name} id:${state.contracts[i].id}");
              }
              print("--------");  

              List<Widget> testList = new List<Widget>();
              for(int i = 0; i < state.contracts.length; i++){
                if(state.contracts[i].isFavorite) testList.add(
                  InkResponse(
                  enableFeedback: true,
                  onLongPress: (){
                    showShortToast();
                    DashBLOC dashBloc = BlocProvider.of<DashBLOC>(context);
                    dashBloc.dispatch(new UnfavRequest(state.contracts[i].id));
                  },
                  onTap: onTap,
                  child:DashboardCardWidget(state.contracts[i])
                  )
              );
              }
              return GridView.count(
                  crossAxisCount: width >= 900 ? 2 : 1,
                  padding: const EdgeInsets.all(2.0),
                  children: testList
              );
            }
          }
      })
    );
  }

full class codedashboard bloc

看起来网格会自行重建,但不要重建其图块。 如何完全更新网格小部件及其所有子小部件?

p.s 我花了两天时间修复它,请帮助

【问题讨论】:

    标签: dart flutter bloc


    【解决方案1】:

    我认为您应该使用GridView.builderconstructor 来指定一个构建函数,该函数将根据项目列表的更改进行更新,因此当您的数据发生任何更新时,BlocBuilder 将触发您的@987654323 中的构建函数@。

    我希望这个例子更清楚。

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: Test(),
        );
      }
    }
    
    class Test extends StatefulWidget {
      @override
      _TestState createState() => _TestState();
    }
    
    class _TestState extends State<Test> {
      List<int> testList = List<int>();
    
      @override
      void initState() {
        for (int i = 0; i < 20; i++) {
          testList.add(i);
        }
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          floatingActionButton: FloatingActionButton(
            //Here we can remove an item from the list and using setState
            //or BlocBuilder will rebuild the grid with the new list data
            onPressed: () => setState(() {testList.removeLast();})
          ),
          body: GridView.builder(
            // You must specify the items count of your grid
            itemCount: testList.length,
            // You must use the GridDelegate to specify row item count
            // and spacing between items
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 5,
              childAspectRatio: 1.0,
              crossAxisSpacing: 1.0,
              mainAxisSpacing: 1.0,
            ),
            // Here you can build your desired widget which will rebuild
            // upon changes using setState or BlocBuilder
            itemBuilder: (BuildContext context, int index) {
              return Text(
                testList[index].toString(),
                textScaleFactor: 1.3,
              );
            },
          ),
        );
      }
    }
    

    【讨论】:

      【解决方案2】:

      您的代码总是发送 int i 的最后一个值。

      所以不是

      for(int i = 0; i < state.contracts.length; i++){
                  if(state.contracts[i].isFavorite) testList.add(
                    InkResponse(
                    enableFeedback: true,
                    onLongPress: (){
                      showShortToast();
                      DashBLOC dashBloc = BlocProvider.of<DashBLOC>(context);
                      dashBloc.dispatch(new UnfavRequest(state.contracts[i].id));
                    },
                    onTap: onTap,
                    child:DashboardCardWidget(state.contracts[i])
                    )
                );
      

                List<Widget> testList = new List<Widget>();
      
                state.contracts.forEach((contract){
                  if(contract.isFavorite) testList.add(
                    InkResponse(
                    enableFeedback: true,
                    onLongPress: (){
                      showShortToast();
                      DashBLOC dashBloc = BlocProvider.of<DashBLOC>(context);
                      dashBloc.dispatch(new UnfavRequest(contract.id));
                    },
                    onTap: onTap,
                    child:DashboardCardWidget(contract)
                    )
                ));
      

      【讨论】:

        【解决方案3】:

        它真的重建了吗?我只是不明白您为什么将 State 与 BLoC 一起使用。即使您使用 State,您也应该调用 setState() 方法来使用新数据更新小部件。 我认为最好的解决方案是尝试从 StatelessWidget 继承您的小部件并在 DashBLOCdispatch(new UpdateRequest()); /strong> 构造函数。

        还要记住这个关于bloc的链接,有很多例子: https://felangel.github.io/bloc/#/

        【讨论】:

          【解决方案4】:

          给孩子一把钥匙

           return  GridView.builder(
                          itemCount: children.length,
                          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(3),
                          itemBuilder: (context, index) {
                            return Container(
                              key: ValueKey(children.length+index),                       
                            );
                          });
          

          【讨论】:

            猜你喜欢
            • 2022-01-22
            • 2021-11-02
            • 2020-07-13
            • 2022-09-30
            • 2021-08-07
            • 1970-01-01
            • 2021-05-26
            • 2019-03-11
            相关资源
            最近更新 更多