首页 > 解决方案 > ListView 未使用 StatefulWidget 重新加载

问题描述

我正在制作一个演示用于学习目的。在我刚刚添加的那个演示中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 没有重新加载。我哪里错了?引导我正确的方向。

标签: dartflutter

解决方案


您的方法存在一些问题

  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())));
            },
          );
        });
  }
}

推荐阅读