Я просмотрел архивы и нашел несколько вопросов по этой теме 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));
});
}
}