【问题标题】:ListView is not reload with StatefulWidgetListView 未使用 StatefulWidget 重新加载
【发布时间】:2018-05-31 06:36:02
【问题描述】:

我正在制作一个演示用于学习目的。在那个演示中,我刚刚添加了ListView,当我点击ListTile 时,有Icons.favorite 我只想做Active 和Deactive。

下面是我的代码。

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 没有改变可能是因为 ListView 没有重新加载。我哪里错了?指引我正确的方向。

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    您的方法存在一些问题

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

    2. 您总是在 ListView.builder 块中创建一个最终列表:final _arraySelectedRowStatus = List.filled(5, 0); 然后使用此列表渲染你的 UI。因此 _arraySelectedRowStatus 将始终包含 0

    下面是更新后的代码

    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】:

      [更新]

      这是完整的工作代码。

      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((){}) 就是这样使用的。

      【讨论】:

      • 删除但没有反映到输出
      • @Govaadiyo 请检查更新的答案以及工作代码和解释。
      • 感谢您的回答它提高了我的知识。
      猜你喜欢
      • 2021-04-08
      • 2020-08-16
      • 2014-05-18
      • 2015-03-21
      • 2017-10-12
      • 2014-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多