Как вызвать ListView refre sh из других элементов в списке - PullRequest
0 голосов
/ 27 мая 2020

Я просмотрел архивы и нашел несколько вопросов по этой теме c, но ни одна из проблем не соответствует моей проблеме. У меня есть список игроков в ListView, который также включает IconButton, строковое имя и флажок. Я хочу имитировать c поведение радиокнопки (то есть взаимоисключающее свойство, при котором может быть выбрана только одна кнопка, нажатие на которую отключает любую другую выбранную «кнопку»). «Радиокнопка» предназначена для указания, кто является «капитаном» команды. В группе может быть только один капитан. На экране по умолчанию будет показан первый игрок как выбранный, нажатие другой строки выделит этот выбор, однако первое имя не будет «отменить выбор». Нажатие флажка для 1-го имени снимет выделение этой строки, а также «потянет список вниз» и будет использовать 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));
        });
  }
}

1 Ответ

0 голосов
/ 28 мая 2020

Вы можете скопировать и вставить полный код ниже
Вы можете передать callback refresh() в _ListLayoutState на PlayerCard
и в PlayerCard позвонить widget.callback()

фрагмент кода

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

рабочая демонстрация

enter image description here

полный код

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,
          );
        });
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...