父小部件中的状态更新未反映在子小部件中

时间:2019-10-24 16:07:17

标签: flutter dart

我有一个带有以下代码的小部件Players

class Players extends StatefulWidget {
  List<Player> players;
  Players(this.players);
  static const pageName = 'Players';
  static const routeName = '/Players';
  @override
  _PlayersState createState() => _PlayersState();
}

class _PlayersState extends State<Players> {
  final _formKey = GlobalKey<FormState>();
  @override
  Widget build(BuildContext context) {
    var _players = widget.players;
    return Scaffold(
      appBar: CustomAppBar(loggedInPlayer.balance),
      body: SafeArea(
          child: ListView(children: <Widget>[
        Container(
            padding: EdgeInsets.only(left: 10, right: 10, top: 10),
            child: Form(
              key: _formKey,
              child: TextFormField(
                onFieldSubmitted: (name) {
                  setState(() {
                    _players = players.where((x) =>
                        x.name.toLowerCase().contains(name.toLowerCase()));
                  });
                },
                decoration: InputDecoration(
                  fillColor: Colors.white,
                  hintText: 'Search a player by name',
                  contentPadding: EdgeInsets.all(10),
                  border: OutlineInputBorder(),
                ),
                // The validator receives the text that the user has entered.
                validator: (value) {
                  if (value.isEmpty) {
                    return 'Please enter some text';
                  }
                  return null;
                },
              ),
            )),
        PlayerGrid(_players)
      ])),
      bottomNavigationBar: CustomBottomNavigationBar(1),
    );
  }
}

它包含一个ListView,ListView中的一个项目是另一个具有以下代码的小部件PlayerGrid

class PlayerGrid extends StatefulWidget {
  List<Player> players;
  PlayerGrid(this.players);
  @override
  _PlayerGridState createState() => _PlayerGridState();
}

class _PlayerGridState extends State<PlayerGrid> {
  List<Player> _players;
  @override
  void initState() {
    super.initState();
    _players = this.widget.players;
  }

  @override
  Widget build(BuildContext context) {
    print(context);
    return GridView.count(
      physics: NeverScrollableScrollPhysics(),
      padding: EdgeInsets.all(5),
      crossAxisCount: 3,
      primary: false,
      crossAxisSpacing: 0,
      mainAxisSpacing: 0,
      childAspectRatio: 0.7,
      shrinkWrap: true,
      children: <Widget>[for (var player in _players) Avatar(player)],
    );
  }
}

现在,在第一个小部件中,我更新表单提交的状态_players。但是,此更新状态不会反映在子窗口小部件PlayerGrid中。我的代码有什么问题?

编辑:

发布更新的代码。

玩家:

class Players extends StatefulWidget {
  List<Player> players;
  Players(this.players);
  static const pageName = 'Players';
  static const routeName = '/Players';
  @override
  _PlayersState createState() => _PlayersState(this.players);
}

class _PlayersState extends State<Players> {
  List<Player> _players;
  _PlayersState(List<Player> players) {
    _players = players;
  }

  final _formKey = GlobalKey<FormState>();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: CustomAppBar(loggedInPlayer.balance),
      body: SafeArea(
          child: ListView(children: <Widget>[
        Container(
            padding: EdgeInsets.only(left: 10, right: 10, top: 10),
            child: Form(
              key: _formKey,
              child: TextFormField(
                onFieldSubmitted: (name) {
                  setState(() {
                    var filteredPlayers = this._players.where((x) =>
                        x.name.toLowerCase().contains(name.toLowerCase()));
                    this._players = filteredPlayers;
                  });
                },
                decoration: InputDecoration(
                  fillColor: Colors.white,
                  hintText: 'Search a player by name',
                  contentPadding: EdgeInsets.all(10),
                  border: OutlineInputBorder(),
                ),
                // The validator receives the text that the user has entered.
                validator: (value) {
                  if (value.isEmpty) {
                    return 'Please enter some text';
                  }
                  return null;
                },
              ),
            )),
        PlayerGrid(this._players)
      ])),
      bottomNavigationBar: CustomBottomNavigationBar(1),
    );
  }
}

PlayerGrid:

class PlayerGrid extends StatelessWidget {
  List<Player> players;
  PlayerGrid(this.players);
  @override
  @override
  Widget build(BuildContext context) {
    return GridView.count(
      physics: NeverScrollableScrollPhysics(),
      padding: EdgeInsets.all(5),
      crossAxisCount: 3,
      primary: false,
      crossAxisSpacing: 0,
      mainAxisSpacing: 0,
      childAspectRatio: 0.7,
      shrinkWrap: true,
      children: <Widget>[for (var player in this.players) Avatar(player)],
    );
  }
}

2 个答案:

答案 0 :(得分:0)

使用TextEditingController()TextFormField获取文本。

示例:

class _PlayersState extends State<Players> {
  var _searchController = TextEditingController();
  List<Player> _players = [];

  _search() {
    {
      if (_formKey.currentState.validate()) {
        _players.clear();
        setState(() {
          var filteredPlayers = widget.players.where((Player x) => x.name
              .toLowerCase()
              .contains(_searchController.text.toLowerCase()));
          _players.addAll(filteredPlayers);
        });
      }
    }
  }

  final _formKey = GlobalKey<FormState>();
  @override
  Widget build(BuildContext context) {
    // var _players = widget.players;
    return Scaffold(
      // appBar: CustomAppBar(loggedInPlayer.balance),
      body: SafeArea(
          child: ListView(children: <Widget>[
        Container(
            padding: EdgeInsets.only(left: 10, right: 10, top: 10),
            child: Form(
              key: _formKey,
              // Create search box
              child: Card(
                child: new ListTile(
                  leading: IconButton(
                    icon: new Icon(Icons.search),
                    onPressed: _search,
                  ),
                  title: new TextFormField(
                    textInputAction: TextInputAction.done,
                    onFieldSubmitted: (_) {
                      _search();
                    },
                    controller: _searchController,
                    decoration: new InputDecoration(
                        hintText: 'Search', border: InputBorder.none),
                    // onChanged: onSearchTextChanged,
                  ),
                  trailing: new IconButton(
                    icon: new Icon(Icons.cancel),
                    onPressed: () {
                      _searchController.clear();
                      // onSearchTextChanged('');
                    },
                  ),
                ),
              ),
            )),
        PlayerGrid(_players)
      ])),
    );
  }
}

答案 1 :(得分:0)

.where()运算符返回Iterable<Player>。在将其分配给状态变量List<Player>之前,将其覆盖到_players

setState(() {
    _players = players
    .where((x) => x.name.toLowerCase().contains(name.toLowerCase())).toList();
});