代码之家  ›  专栏  ›  技术社区  ›  Govaadiyo

ListView未使用StatefulWidget重新加载

  •  0
  • Govaadiyo  · 技术社区  · 7 年前

    我正在做一个学习演示。在演示中我刚刚添加了 ListView 当我点击 ListTile Icons.favorite 我只想做积极的和不积极的。

    下面是我的代码。

    import 'package:flutter/material.dart';
    
    void main() => runApp(new RandomWordApp());
    
    class RandomWordApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return new MaterialApp(
          title: "Random App",
          home: new RandomWordHome(),
        );
      }
    }
    
    class RandomWordHome extends StatefulWidget {
      @override
      createState() => new RandomState();
    }
    
    class RandomState extends State<RandomWordHome> {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return new Scaffold(
          appBar: new AppBar(
            title: new Text("Random Word"),
          ),
          body: setupListView(),
        );
      }
    
      Widget setupListView() {
        final _arrayOfData = [
          {
            "name": "Amit Patel",
            "address": "Junagadh"
          },
          {"name": "Arjun Jain", "address": "Madhya Pradesh"},
          {"name": "Ajay Shah", "address": "Limbadi"},
          {"name": "Ankur Patel", "address": "Visanagar"},
          {"name": "Soheb Ansari", "address": "Ahmedabad"}
        ];    
        final _arraySelectedRowStatus = List.filled(5, 0);
    
        return new ListView.builder(
            padding: new EdgeInsets.all(10.0),
            itemCount: _arrayOfData.length,
            itemBuilder: (context, i) {
              return new ListTile(
                title: new Text(_arrayOfData[i]["name"]),
                subtitle: new Text(_arrayOfData[i]["address"]),
                leading: new CircleAvatar(
                    backgroundColor: Colors.blue,
                    child: new Text(_arrayOfData[i]["name"][0])),
                trailing: new Icon(
                  (_arraySelectedRowStatus[i] == 0
                      ? Icons.favorite_border
                      : Icons.favorite),
                  color: (_arraySelectedRowStatus[i] == 0 ? null : Colors.red),
                ),
                onTap: () {
                  setState(
                    () {
                      _arraySelectedRowStatus[i] =
                          (_arraySelectedRowStatus[i] == 0 ? 1 : 0);         
                      Scaffold.of(context).showSnackBar(new SnackBar(
                          content:
                              new Text("You are selecting at " + i.toString())));
                    },
                  );
                },
              );
            });
      }
    }
    

    所有的工作都很好,甚至我从下面得到了预期的输出

    print(_arrayOfData[i]["name"] + " - " + _arraySelectedRowStatus[i].toString());
    

    但是 Icon is not change可能是因为listview没有重新加载。我哪里做错了?引导我往正确的方向走。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Phuc Tran    7 年前

    你的方法有些问题

    1. 为了更新用户界面,必须使用setState()方法。仅仅改变变量是不够的。

    2. 始终在listview.builder块中创建最终列表: final _arrayselectedrowstatus=列表。已填充(5,0); 然后使用此列表呈现用户界面。因此,arrayselectedrowstatus将始终包含 .

    下面是更新后的代码

    import 'package:flutter/material.dart';
    
    void main() => runApp(new RandomWordApp());
    
    class RandomWordApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return new MaterialApp(
          title: "Random App",
          home: new RandomWordHome(),
        );
      }
    }
    
    class RandomWordHome extends StatefulWidget {
      @override
      createState() => new RandomState();
    }
    
    class RandomState extends State<RandomWordHome> {
      List _arraySelectedRowStatus = List.filled(5, 0);
    
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return new Scaffold(
          appBar: new AppBar(
            title: new Text("Random Word"),
          ),
          body: setupListView(),
        );
      }
    
      Widget setupListView() {
        final _arrayOfData = [
          {"name": "Amit Patel", "address": "Junagadh"},
          {"name": "Arjun Jain", "address": "Madhya Pradesh"},
          {"name": "Ajay Shah", "address": "Limbadi"},
          {"name": "Ankur Patel", "address": "Visanagar"},
          {"name": "Soheb Ansari", "address": "Ahmedabad"}
        ];
    
        return new ListView.builder(
            padding: new EdgeInsets.all(10.0),
            itemCount: _arrayOfData.length,
            itemBuilder: (context, i) {
              return new ListTile(
                title: new Text(_arrayOfData[i]["name"]),
                subtitle: new Text(_arrayOfData[i]["address"]),
                leading: new CircleAvatar(
                    backgroundColor: Colors.blue,
                    child: new Text(_arrayOfData[i]["name"][0])),
                trailing: new Icon(
                  (_arraySelectedRowStatus[i] == 0
                      ? Icons.favorite_border
                      : Icons.favorite),
                  color: (_arraySelectedRowStatus[i] == 0 ? null : Colors.red),
                ),
                onTap: () {
                  _arraySelectedRowStatus[i] =
                      (_arraySelectedRowStatus[i] == 0 ? 1 : 0);
                  print(_arrayOfData[i]["name"] +
                      " - " +
                      _arraySelectedRowStatus[i].toString());
    
                  setState(() {
                    _arraySelectedRowStatus = _arraySelectedRowStatus;
                  });
    
                  Scaffold.of(context).showSnackBar(new SnackBar(
                      content: new Text("You are selecting at " + i.toString())));
                },
              );
            });
      }
    }
    
        2
  •  1
  •   Dhrumil Shah - dhuma1981    7 年前

    [更新]

    这是完整的工作代码。

    class DemoHelp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // TODO: implement build
        return MaterialApp(
          title: "Random App",
          home: RandomWorldHome(),
        );
      }
    }
    
    class RandomWorldHome extends StatefulWidget {
      @override
      _RandomWorldHomeState createState() => new _RandomWorldHomeState();
    }
    
    class _RandomWorldHomeState extends State<RandomWorldHome> {
    
      List<int> _arraySelectedRowStatus = List.filled(5, 1);
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: AppBar(
            title: Text("Random Word"),
          ),
          body: setupListView(),
        );
      }
    
      Widget setupListView() {
        final _arrayOfData = [
          {"name": "Amit Patel", "address": "Junagadh"},
          {"name": "Arjun Jain", "address": "Madhya Pradesh"},
          {"name": "Ajay Shah", "address": "Limbadi"},
          {"name": "Ankur Patel", "address": "Visanagar"},
          {"name": "Soheb Ansari", "address": "Ahmedabad"}
        ];
    
    
        return ListView.builder(
          padding: new EdgeInsets.all(10.0),
          itemCount: _arrayOfData.length,
          itemBuilder: (context, i) {
            return ListTile(
              title: Text(_arrayOfData[i]["name"]),
              subtitle: new Text(_arrayOfData[i]["address"]),
              leading: new CircleAvatar(
                  backgroundColor: Colors.blue,
                  child: new Text(_arrayOfData[i]["name"][0])),
              trailing: new Icon(
                (_arraySelectedRowStatus[i] == 0
                    ? Icons.favorite_border
                    : Icons.favorite),
                color: (_arraySelectedRowStatus[i] == 0 ? null : Colors.red),
              ),
              onTap: (){
                setState(() {
                  _arraySelectedRowStatus[i] = _arraySelectedRowStatus[i] == 0 ? 1 : 0;
                });
                Scaffold.of(context).showSnackBar(new SnackBar(
                    content:
                    new Text("You are selecting at ${_arraySelectedRowStatus[i]}")));
              },
            );
          },
        );
      }
    }
    

    代码中有几个问题。

    1. 变量arrayselectedrowstatus被错误地定义为final
    2. 状态变量应该在状态类中声明,而不是在方法中声明。
    3. setState((){})是这样使用的。