#flutter #riverpod
#flutter #riverpod
Вопрос:
Как показано на рисунке, я пытаюсь создать список кубиков, в которые я могу добавить или удалить кубик. Я пробовал stateProvider, ChangeNotifier и StateNotifier. Кажется, что каждый из них работает не так, как я ожидаю. Я пытаюсь создать провайдера, который содержит список dieWidgets, но я не могу понять, как удалить конкретный штамп, когда я долго нажимаю на него. На изображении показано всплывающее меню для его удаления, это долгосрочная цель, но сейчас было бы неплохо просто удалить его длинным нажатием. Мысли о том, как подойти к этому?
main.dart
class DiceNotifier extends ChangeNotifier {
List<DieWidget> dice = [];
void add() {
dice.add(DieWidget());
notifyListeners();
}
void removeDie(int id) {
// FIXME: Unable to delete a die based on id
print(id);
notifyListeners();
}
}
final diceProvider = ChangeNotifierProvider((_) {
return DiceNotifier();
});
class MyHomePage extends ConsumerWidget {
@override
Widget build(BuildContext context, ScopedReader watch) {
final dice = watch(diceProvider).dice;
return Scaffold(
appBar: AppBar(
title: Text("Dice"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
...dice,
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
context.read(diceProvider).add();
},
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
die_widget.dart
class DieWidget extends StatefulWidget {
@override
_DieWidgetState createState() => _DieWidgetState();
}
class _DieWidgetState extends State<DieWidget> {
int value = 0;
int id = 0;
@override
Widget build(BuildContext context) {
return FlatButton(
child: Text(
'$value',
),
onPressed: () {
setState(() {
value ;
id ;
});
// context.read(dieProvider).increment();
},
onLongPress: () {
final dice = context.read(diceProvider);
dice.removeDie(id);
// print(this.value);
},
);
}
}
Ответ №1:
Одним из решений было бы определить параметр value
в DiceWidget
классе:
class DiceWidget extends StatefulWidget {
const DiceWidget({ Key key, this.value }) : super(key: key);
int value;
@override
_DiceWidgetState createState() => _DiceWidgetState();
}
И получить доступ к этим данным из DiceWidget
:
class DiceWidget extends StatefulWidget {
@override
_DiceWidgetState createState() => _DiceWidgetState();
}
class _DiceWidgetState extends State<DiceWidget> {
@override
Widget build(BuildContext context) {
return FlatButton(
child: Text(
widget.value.toString() ?? '',
),
onLongPress: () {
final dice = context.read(diceProvider);
dice.removeDice(widget.value);
// print(widget.value);
},
);
}
}
В DiceNotifier
классе я бы рекомендовал реализовать dices
массив как List<int>
:
List<int> dices = [];
Следовательно, функции addDice()
и removeDice()
будут, соответственно:
class DiceNotifier extends ChangeNotifier {
List<int> dices = [];
void addDice() {
dices.add(dices.length);
notifyListeners();
}
void removeDice(int id) {
dices.remove(id);
print(id);
notifyListeners();
}
}
Чтобы заставить пример работать, нам MyHomePage
Column
children
также нужно изменить, чтобы построить список DiceWidget
:
...dices.map((d) => DiceWidget(value: d)).toList(),
Тогда весь пример будет выглядеть следующим образом:
main.dart
:
class DiceNotifier extends ChangeNotifier {
List<int> dices = [];
void addDice() {
dices.add(dices.length);
notifyListeners();
}
void removeDice(int id) {
dices.remove(id);
print(id);
notifyListeners();
}
}
final diceProvider = ChangeNotifierProvider((_) {
return DiceNotifier();
});
class MyHomePage extends ConsumerWidget {
@override
Widget build(BuildContext context, ScopedReader watch) {
final dices = watch(diceProvider).dices;
return Scaffold(
appBar: AppBar(
title: Text("Dice"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
...dices.map((d) => DiceWidget(value: d)).toList(),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
context.read(diceProvider).addDice();
},
child: Icon(Icons.add),
),
);
}
}
dice_widget.dart
:
class DiceWidget extends StatefulWidget {
@override
_DiceWidgetState createState() => _DiceWidgetState();
}
class _DiceWidgetState extends State<DiceWidget> {
@override
Widget build(BuildContext context) {
return FlatButton(
child: Text(
widget.value.toString() ?? '',
),
onLongPress: () {
final dice = context.read(diceProvider);
dice.removeDice(widget.value);
print(widget.value);
},
);
}
}
Комментарии:
1. Это потрясающе! Большое вам спасибо за ваше время и помощь. Мне нужно еще немного посидеть и разобраться в логике всего этого. Еще раз спасибо 🙂