如何使用颤振提供者监听列表中的变化?
Posted
技术标签:
【中文标题】如何使用颤振提供者监听列表中的变化?【英文标题】:How to listen for change within a list using flutter provider? 【发布时间】:2020-09-19 03:27:52 【问题描述】:我有一个提供程序正在监听 playerList
类的更改:
import 'package:flutter/material.dart';
import 'package:scam_artist/constants/PlayerColors.dart';
import 'package:scam_artist/models/Player.dart';
class PlayerList with ChangeNotifier
List<Player> _players = [];
List<Player> get players
return [..._players];
void addPlayer(Key key, String name, int index)
_players.add(
new Player(key: key, color: PlayerColors.colors[index], name: name));
notifyListeners();
void editPlayerName(String newName, int index)
_players[index].name = newName;
notifyListeners();
void editPlayerColor(Color newColor, int index)
_players[index].color = newColor;
notifyListeners();
但是,当我调用函数将值更改为 Player
对象之一(例如更改名称)时,列表不会使用新数据更新对象。
Player
类是否需要另一个提供程序?如果是这样,我如何让PlayerList
提供者监听Player
提供者的变化?
做了一些研究,我认为 ProxyProvider 可能是我正在寻找的东西,但我不确定如何实现它。
如果有帮助,这是我的 Player
课程:
import 'package:flutter/material.dart';
class Player
// id will be for database if implemented
String uid;
Key key;
String name;
//position is the order where the player plays
int position;
Color color;
bool isTurn;
bool isFakeArtist;
bool isWinner;
Player(this.key, this.name, this.color);
这就是我创建ChangeNotifierProvider
的地方:
import 'package:flutter/material.dart';
import 'package:scam_artist/UserListener.dart';
import 'package:scam_artist/models/user.dart';
import 'package:scam_artist/providers/PlayerList.dart';
import 'package:scam_artist/services/AuthService.dart';
import 'package:provider/provider.dart';
import 'package:scam_artist/views/Lobby.dart';
void main()
runApp(MyApp());
class MyApp extends StatelessWidget
// This widget is the root of your application.
@override
Widget build(BuildContext context)
return MultiProvider(
providers: [
StreamProvider<User>.value(value: AuthService().user),
ChangeNotifierProvider(create: (context) => PlayerList())
],
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: UserListener(),
routes: Lobby.routeName: (ctx) => Lobby(),
),
);
【问题讨论】:
我也有同样的问题。你有没有设法修复它?我已经尝试将notifyListeners()
发送到列表的每个对象,并在我执行更新时调用它,但行为仍然存在。有任何想法吗?另外,我目前正在将 ProxyProvider 用于其他事情,并且可以正常工作,但那是为了让一个提供者监听另一个提供者的更改,我不知道如何创建提供者的动态列表(播放器)来使用它们方式。
【参考方案1】:
这里有很多问题。
1.修复您的 PlayerList 声明行。
//CORRECT
class PlayerList extends ChangeNotifier ...
//WRONG
class PlayerList with ChangeNotifier ...
4.修正你的球员吸气剂线。
使用这个:
List<Player> get players => _players;
3。您需要更多关于提供者的概念知识。
基本上,Provider 使您的 PlayerList 可以从您提供它的下方小部件树中的任何位置访问。例如,您从MaterialApp
的顶部提供。所以你可以通过HomePage
或Lobby
访问它。
要访问您的PlayerList
,您必须使用Consumer
小部件或Selector
小部件,但对于您的情况,Consumer
就足够了。 Selector
用于高级用途。
这是从您的PlayerList
读取实时值的代码。
class Lobby extends StatelessWidget
@override
Widget build(BuildContext context) => Scaffold(
body: _body(),
);
_body() => Container(
child: Consumer<PlayerList>(
builder: (BuildContext context, PlayerList bloc) =>
ListView.builder(
itemCount: bloc.players.length,
itemBuilder:
(BuildContext context, int index) => Text(bloc.players[index].name),
),
),
);
【讨论】:
【参考方案2】:只需更改您的 _players
访问器,您应该会很好。
List<Player> get players
return _players;
【讨论】:
【参考方案3】:我也遇到了同样的问题。
我解决它的一种方法(虽然不是最漂亮的)是在 ChangeNotifier 中有一个方法来返回一个特定的对象,然后观察变化,例如
// in ChangeNotifier
Player getPlayer(int index) => _players[index];
然后在小部件中有
context.watch<PlayerList>().getPlayer(index).updateName("newName")
【讨论】:
以上是关于如何使用颤振提供者监听列表中的变化?的主要内容,如果未能解决你的问题,请参考以下文章
知道应用程序内部的信息作为另一个类中的列表存在,我如何在颤振中使用搜索