【问题标题】:How to trigger ListView refresh from other items in the list如何从列表中的其他项目触发 ListView 刷新
【发布时间】:2020-05-27 17:50:11
【问题描述】:

我搜索了档案并找到了关于这个主题的几个问题,但没有一个问题与我的问题完全匹配。我在 ListView 中有一个玩家列表,其中还包括一个 IconButton、一个字符串名称和一个复选框。我想模仿单选按钮的行为(即一个互斥属性,其中只能选择一个按钮,按下一个按钮会关闭任何其他选定的“按钮”)。 “单选按钮”旨在表明谁是团队的“队长”。组内只能有一名队长。默认屏幕将显示第一个玩家被选中,按下另一行将突出显示该选择,但是,名字不会“取消选择”。按下第一个名称的复选框将取消突出显示该行以及“下拉列表”并使用 RefreshIndicator。但只需按下图标按钮对其他行没有影响。

我看到了几个关于向列表中添加项目和自动刷新 ListView 的主题,但是当从不同的行激活 onPressed 函数时,我找不到任何关于更新列表中其他项目的信息。我尝试添加 didChangeDependencies 认为可能会更新其他 listView 项目,但我也无法让它工作。

我是否缺少一些允许此功能的设置?

import 'package:flutter/material.dart';

Group group;

class Player {
  String name;
  bool captain;
  bool press;

  Player({this.captain, this.name, this.press});
}

class Group {
  List<Player> players = [];

  void addNewPlayer(String name, bool banker, bool pressing) {
    final player = Player(name: name, captain: banker, press: pressing);
    players.add(player);
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(title: 'Players'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({this.title});

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    group = Group();
    for (int i = 1; i <= 4; i++) {
      group.addNewPlayer('Player $i', i == 1, false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: RefreshIndicator(
        child: ListLayout(),
        onRefresh: _handleRefresh,
      ),
    );
  }

  Future<Null> _handleRefresh() async {
    setState(() {
      ListLayout();
    });

    return null;
  }
}

class PlayerCard extends StatefulWidget {
  final int curPlayer;
  final Group group;

  PlayerCard({Key key, this.group, this.curPlayer}) : super(key: key);

  @override
  _PlayerCardState createState() => _PlayerCardState();
}

class _PlayerCardState extends State<PlayerCard> {
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    setState(() {
      ListLayout();
    });
  }

  @override
  Widget build(BuildContext context) {
    var group = widget.group;
    var curPlayer = widget.curPlayer;

    return Container(
      child: Card(
        color:
            group.players[curPlayer].captain ? Colors.lightBlue : Colors.white,
        child: Row(
          children: <Widget>[
            IconButton(
              icon: Icon(Icons.adjust),
              onPressed: () {
                setState(() {
                  for (int i = 0; i < group.players.length; i++) {
                    group.players[i].captain = (i == widget.curPlayer);
                  }

                  didChangeDependencies();
                });
              },
            ),
            Expanded(
              child: Column(
                children: <Widget>[
                  Text(
                    group.players[curPlayer].name,
                  ),
                ],
              ),
            ),
            Expanded(
              flex: 1,
              child: Checkbox(
                value: group.players[curPlayer].press,
                onChanged: (value) {
                  setState(
                    () {
                      group.players[curPlayer].press = value;
                    },
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class ListLayout extends StatefulWidget {
  @override
  _ListLayoutState createState() => _ListLayoutState();
}

class _ListLayoutState extends State<ListLayout> {
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        shrinkWrap: true,
        itemCount: group.players.length,
        itemBuilder: (context, index) {
          return PlayerCard(
              curPlayer: index, group: group, key: ValueKey(group));
        });
  }
}

【问题讨论】:

  • 你认为setState(() {ListLayout();});在做什么?

标签: listview flutter


【解决方案1】:

您可以在下面复制粘贴运行完整代码
您可以将_ListLayoutState 中的callback refresh() 传递给PlayerCard
并在PlayerCard 中调用widget.callback()

代码sn-p

class PlayerCard extends StatefulWidget {
 ...
  final VoidCallback callback;
  PlayerCard({Key key, this.group, this.curPlayer, this.callback})
      : super(key: key);

   ...    
   onPressed: () {
                setState(() {
                  ...
                  widget.callback();    

class _ListLayoutState extends State<ListLayout> {
  void refresh() {
    setState(() {});
  }
  ...
  return PlayerCard(
            curPlayer: index,
            group: group,
            key: ValueKey(group),
            callback: refresh,
          );

工作演示

完整代码

import 'package:flutter/material.dart';

Group group;

class Player {
  String name;
  bool captain;
  bool press;

  Player({this.captain, this.name, this.press});
}

class Group {
  List<Player> players = [];

  void addNewPlayer(String name, bool banker, bool pressing) {
    final player = Player(name: name, captain: banker, press: pressing);
    players.add(player);
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(title: 'Players'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({this.title});

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    group = Group();
    for (int i = 1; i <= 4; i++) {
      group.addNewPlayer('Player $i', i == 1, false);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: RefreshIndicator(
        child: ListLayout(),
        onRefresh: _handleRefresh,
      ),
    );
  }

  Future<Null> _handleRefresh() async {
    setState(() {
      ListLayout();
    });

    return null;
  }
}

class PlayerCard extends StatefulWidget {
  final int curPlayer;
  final Group group;
  final VoidCallback callback;
  PlayerCard({Key key, this.group, this.curPlayer, this.callback})
      : super(key: key);

  @override
  _PlayerCardState createState() => _PlayerCardState();
}

class _PlayerCardState extends State<PlayerCard> {
  /*@override
  void didChangeDependencies() {
    super.didChangeDependencies();
    setState(() {
      ListLayout();
    });
  }*/

  @override
  Widget build(BuildContext context) {
    var group = widget.group;
    var curPlayer = widget.curPlayer;

    return Container(
      child: Card(
        color:
            group.players[curPlayer].captain ? Colors.lightBlue : Colors.white,
        child: Row(
          children: <Widget>[
            IconButton(
              icon: Icon(Icons.adjust),
              onPressed: () {
                setState(() {
                  for (int i = 0; i < group.players.length; i++) {
                    group.players[i].captain = (i == widget.curPlayer);
                  }
                  widget.callback();
                  //didChangeDependencies();
                });
              },
            ),
            Expanded(
              child: Column(
                children: <Widget>[
                  Text(
                    group.players[curPlayer].name,
                  ),
                ],
              ),
            ),
            Expanded(
              flex: 1,
              child: Checkbox(
                value: group.players[curPlayer].press,
                onChanged: (value) {
                  setState(
                    () {
                      group.players[curPlayer].press = value;
                    },
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}

class ListLayout extends StatefulWidget {
  @override
  _ListLayoutState createState() => _ListLayoutState();
}

class _ListLayoutState extends State<ListLayout> {
  void refresh() {
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        shrinkWrap: true,
        itemCount: group.players.length,
        itemBuilder: (context, index) {
          return PlayerCard(
            curPlayer: index,
            group: group,
            key: ValueKey(group),
            callback: refresh,
          );
        });
  }
}

【讨论】:

  • 效果很好,这正是我想要的!谢谢。
  • 很高兴为您提供帮助。如果对您有帮助,请将其标记为答案。谢谢。
猜你喜欢
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 2019-05-26
  • 2011-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多