Flutterプロバイダーを使用してリスト内の変更をリッスンする方法は? 質問する

Flutterプロバイダーを使用してリスト内の変更をリッスンする方法は? 質問する

クラスの変更をリッスンしているプロバイダーがあります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オブジェクトの 1 つの値を変更すると (たとえば、名前を変更すると)、リストはオブジェクトを新しいデータで更新しません。

クラスに別のプロバイダーが必要ですか? もしそうなら、プロバイダーがプロバイダーの変更をリッスンするようにするにはPlayerどうすればよいですか?PlayerListPlayer

少し調べてみると、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()},
      ),
    );
  }
}

ベストアンサー1

ここには間違いが複数あります。

1. PlayerList 宣言行を修正します。

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

4. プレーヤーのゲッターラインを修正します。

これを使って:

List<Player> get players => _players;

3. プロバイダーに関する概念的な知識がさらに必要です。


基本的に、プロバイダーは、PlayerList を、それを提供した場所の下のウィジェット ツリー内のどこからでもアクセスできるようにします。たとえば、 の上から を提供しているとします。そのため、またはMaterialAppでアクセスできます。HomePageLobby

にアクセスするには、ウィジェットまたはウィジェットPlayerListを使用する必要がありますが、この場合、 で十分です。は高度な使用法向けです。ConsumerSelectorConsumerSelector

以下は、 からライブ値を読み取るためのコードです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),
          ),
    ),

  );

}

おすすめ記事