重新加载无状态小部件后,我应该如何更新?

时间:2020-07-25 18:40:35

标签: flutter dart

我正在使用JSON文件存储要显示和更新的列表。我有一个StatefulWidget(称为“ HOME”),它使用ListView.builder显示列表。我还有一个StatefulWidget(称为“ ADD”),该对象将对象添加到列表中并更新JSON文件。当我完成添加列表后,导航回到“ HOME”,我收到此错误: Error Upon Returning to HOME

enter image description here
主页:

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {

  PlayerList playerList;



  @override
  void initState() {
    super.initState();
    readPlayerData().then((PlayerList list) {
      playerList = list;
    });

    
  }

  @override
  Widget build(BuildContext context) {

    // add Player to the PlayerList
    void addPlayer() async {
      await Navigator.pushReplacement(
        context,
        MaterialPageRoute(builder: (context) => AddPlayer()),
      );

      initState();
    }

    void removePlayer(int index) async {

      playerList.players.removeAt(index);
      await writePlayerData(playerList);
    }

    playerList = ModalRoute.of(context).settings.arguments;

    return Scaffold(
      backgroundColor: Colors.grey[900],
      appBar: AppBar(
        title: Text('Smash Tracker'),
        centerTitle: true,
        backgroundColor: Colors.grey[850],
        elevation: 0,
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {addPlayer();},
        child: Icon(Icons.add),
        backgroundColor: Colors.grey[600],
      ),
      body: Padding(
        padding: EdgeInsets.all(15.0),
        child: Container(
          child: Card(
            color: Colors.grey[900],
            shadowColor: Colors.black87,
            child: ListView.builder(
              itemCount: playerList.players.length,
              itemBuilder: (context, index) {
                return ListTile(
                  //leading: characterIcons(playerList.players[index]),
                  title: Text(
                    playerList.players[index].playerId,
                    style: TextStyle(
                      color: Colors.amberAccent,
                    ),
                  ),
                  subtitle: Text(
                    playerList.players[index].playerSetCount,
                    style: TextStyle(
                      color: Colors.amberAccent,
                    ),
                  ),
                  onTap: () {
                    Navigator.pushNamed(context, '/playerCard', arguments: {
                      'player': playerList.players[index],
                      'playerList': playerList,
                      'index': index
                    });
                  },
                  trailing: IconButton(
                    onPressed: () async {
                      removePlayer(index);
                      PlayerList newPlayerList = await readPlayerData();
                      setState(()  {
                        playerList = newPlayerList;
                      });
                      },
                    icon: Icon(Icons.delete_outline),
                    color: Colors.white,
                  ),
                );
              },
            ),
          ),
        ),
      ),
    );
  }

}

按下“保存”按钮时用于保存新对象的代码
添加:

  void _saveForm() async {
      
      PlayerList playerList = await readPlayerData();

      Player newPlayer = new Player("${playerName.trim()}", "0 - 0",
          new Characters(_myChar1Result, _myChar2Result), "");
      playerList.players.add(newPlayer);

      await writePlayerData(playerList);

      Navigator.pushReplacement(
        context,
        MaterialPageRoute(builder: (context) => Home()),
      );
  }

我认为,当ListView.builder试图调用playerList对象时,会发生错误。我不确定。我很乐意提供其他信息。
“编辑:”这是readPlayerData(),包括其依赖的方法:

Future<PlayerList> readPlayerData () async {
  try {
    final file = await _localFile;
    String contents = await file.readAsString();
    final jsonResponse = (jsonDecode(contents)); //wrap in encode
    PlayerList playerList = PlayerList.fromJson(jsonResponse);
    return playerList;
  } catch (e) {
    print(e);
    return getPlayerList(); //just loads a placeholder json in the assets folder;
  }

Future<String> get _localPath async {
  final directory = await getApplicationDocumentsDirectory();
  return directory.path;
}

Future<File> get _localFile async {
  final path = await _localPath;
  print(path);
  return File('$path/playerData.json');
}

json文件保存了我想要的方式。

1 个答案:

答案 0 :(得分:2)

您的代码中存在多个问题,这就是我解决的方法。

解决方案,我会明智地为您提供解决方案文件,因此请继续进行操作

1。主页

  • 删除方法=> addPlayer()removePlayer()
  • setState((){})中为playerList添加initState()
  • 完全删除此行,playerList = ModalRoute.of(context).settings.arguments;。无法在此行中使用越野车
  • Navigator.pushAndRemoveUntil()addPlayer()的正确用法
class _HomeState extends State<Home> {
  PlayerList playerList;

  @override
  void initState() {
    super.initState();
    readPlayerData().then((PlayerList list) {
      setState(() => playerList = list);
    });
  }

  // add Player to the PlayerList
  void addPlayer() async {
    Navigator.pushAndRemoveUntil(
        context,
        MaterialPageRoute(builder: (context) => AddPlayer()),
        (_) => false);

    //initState();
  }

  void removePlayer(int index) async {
    playerList.players.removeAt(index);
    await writePlayerData(playerList);
  }

  @override
  Widget build(BuildContext context) {
    // copy paste your Scaffold content here
    // rest everything will be same
    // NO layerList = ModalRoute.of(context).settings.arguments;
    return Scaffold();
  }
}

2。添加

  • 字符模态的导入是错误的,并且存在冲突。应该像import 'package:smash_tracker/models/character_model.dart' as Characters;
  • 那样导入
  • 然后在传递对象时,应像这样new Characters.Characters(_myChar1Result, _myChar2Result)
  • 正确使用Navigator.pushAndReplaceUntil()
  • 在小部件{} PlayerList playerList = ModalRoute.of(context).settings.arguments;内删除此行
  • 其他地方都一样
import 'package:smash_tracker/models/character_model.dart' as Characters;

void _saveForm() async {
    setState(() {
      _myChar1Result = _myChar1;
      _myChar2Result = _myChar2;
    });

    PlayerList playerList = await readPlayerData();

    Player newPlayer = new Player("${playerName.trim()}", "0 - 0",
        new Characters.Characters(_myChar1Result, _myChar2Result), "");
    playerList.players.add(newPlayer);

    print('added new Player');
    await writePlayerData(playerList);
    print('updated JSON');

    Navigator.pushAndRemoveUntil(
        context,
        MaterialPageRoute(builder: (context) => Home())
        (_) => false);
  }

  @override
  Widget build(BuildContext context) {
    // no more PlayerList playerList = ModalRoute.of(context).settings.arguments;
    return Scaffold();
  }

测试该应用程序后,其工作原理如下所示。

Result GIF