【问题标题】: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 用于其他事情,并且可以正常工作,但那是为了让一个提供者监听另一个提供者的更改,我不知道如何创建提供者的动态列表(播放器)来使用它们方式。

标签: flutter flutter-provider


【解决方案1】:

这里有很多问题。

1.修复您的 PlayerList 声明行。

//CORRECT
class PlayerList extends ChangeNotifier {...}
//WRONG
class PlayerList with ChangeNotifier {...}

4.修正你的球员吸气剂线。

使用这个:

List<Player> get players => _players;

3。您需要更多关于提供者的概念知识。


基本上,Provider 使您的 PlayerList 可以从您提供它的下方小部件树中的任何位置访问。例如,您从MaterialApp 的顶部提供。所以你可以通过HomePageLobby 访问它。

要访问您的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")
      

      【讨论】:

        猜你喜欢
        • 2021-11-01
        • 1970-01-01
        • 2019-12-08
        • 2021-01-28
        • 2022-11-02
        • 2020-05-10
        • 2019-12-12
        • 2020-12-24
        • 2022-08-19
        相关资源
        最近更新 更多