質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Q&A

解決済

1回答

528閲覧

sink.addしているのにstreamでhasDataがfalseになってしまう.

hiro094

総合スコア26

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

0グッド

0クリップ

投稿2020/02/05 07:54

flutterでデータを取得しListViewで表示するというものをBlocパターンで作製しているのですが、sink.addのタイミングでデバッグで止めると値は取れているのですが、streambuilder内でhasDataがfalseになってしまいます。

どこが原因なのでしょうか?

構造はTabBarScreen -> Screenになっていてその中でListViewを表示しようとしています。
Providerはここで噛ませています。

TabBarScreen.dart

1lass TabInfo { 2 String label; 3 Widget widget; 4 TabInfo(this.label, this.widget); 5} 6 7class TabBarScreen extends StatelessWidget { 8 final List<TabInfo> _tabs = [ 9 TabInfo( 10 "CARDS", 11 CardBlocProvider( 12 key: PageStorageKey<String>("key_card_screen"), 13 bloc: CardBloc(), 14 child: CardsScreen(), 15 ), 16 //... 17 ) 18 ]; 19 20 @override 21 Widget build(BuildContext context) { 22 return DefaultTabController( 23 length: _tabs.length, 24 child: Scaffold( 25 appBar: AppBar( 26 leading: new Container(), 27 title: Text(""), 28 bottom: TabBar( 29 isScrollable: true, 30 tabs: _tabs.map((TabInfo tab) { 31 return Tab(text: tab.label); 32 }).toList(), 33 ), 34 ), 35 36 body: TabBarView(children: _tabs.map((tab) => tab.widget).toList()), 37 ) 38 ); 39 } 40}

CardsScreen.dart

1class CardsScreen extends StatefulWidget { 2 CardsScreen({Key key, this.title}) : super(key: key); 3 final String title; 4 5 @override 6 _CardsScreenState createState() => new _CardsScreenState(); 7} 8 9class _CardsScreenState extends State<CardsScreen> with AutomaticKeepAliveClientMixin<CardsScreen>{ 10 TextEditingController editingController = TextEditingController(); 11 12 //... 13 14 @override 15 Widget build(BuildContext context) { 16 var bloc = CardBlocProvider.of(context); 17 18 var searchView = TextField( 19 //... 20 ); 21 22 var stream = StreamBuilder( 23 stream: bloc.cardsInitialStream, 24 builder: (context, snap) { 25 //ここでsnap.hasDataがfalseになってしまうためロードのままになってしまう。 26 if(!snap.hasData) return LinearProgressIndicator(); 27 28 return ListView.builder( 29 itemBuilder: (BuildContext context, int index){ 30 return Container( 31 child:ListTile( 32 //... 33 ), 34 ); 35 }, 36 itemCount: snap.data.list.length, 37 ); 38 }); 39 40 var contentBody = Container( 41 child: Column( 42 children: <Widget>[ 43 Padding( 44 padding: const EdgeInsets.all(8.0), 45 child: stream 46 ), 47 ], 48 ), 49 ); 50 51 return Scaffold( 52 body: contentBody, 53 floatingActionButton: _createFloationgActionButton(), 54 ); 55 }

sink.addのタイミングではデバッグでデータが渡ってきているが、streamで見るタイミングではhasDataはfalseになってしまう。

class CardBloc { final _cardsInitialPublishSubject = PublishSubject<CardListModel>(); CardBloc() { fetchCards(); } Stream<CardListModel> get cardsInitialStream => _cardsInitialPublishSubject.stream; Sink<CardListModel> get cardsInitialSink => _cardsInitialPublishSubject.sink; void fetchCards() async { final _cardsResponse = await CardRepository().fetchCardRepository(); //ここをデバッグで見ると<CardListModel>のデータが渡ってきているが、Streamではデータが無いとなってしまう。 cardsInitialSink.add(_cardsResponse); } void dispose() { _cardsInitialPublishSubject.close(); } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

dart

1// PublishSubject<CardListModel>(); 2BehaviorSubject<CardListModel>();

これでどうでしょうか?

投稿2020/02/05 10:35

_Victorique__

総合スコア1392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hiro094

2020/02/05 11:05

ありがとうございます!表示できました! 初期値を使う場合はBehaviorSubjectでそうでなければPublishSubjectというのを見様見真似で使っていたのですが、今回初期値を使っていないのですが、hasDataがtrueにならないのはどのような原因だったのでしょうか・・・?
iMASAKI

2020/04/05 01:00

アドバイスになるか分かりませんが・・・ PublishSubjectで作ったStreamを使ってウィジェットを表示しようとすると、 そのウィジェットが描画される前までにsink.addされたデータは受け取ることができません。
hiro094

2020/04/20 06:18

ありがとうございます! そうだったのですね・・・と言うことは初期値を特に入れる理由がなかったとしてもBehaviorSubjectを使う方が良いんですかね? そうなるとPublishSubjectっていつ使うのでしょう・・・?(主の質問とは違いますが)
iMASAKI

2020/04/24 10:53

Behavior Subjectはlisten前の状態を持ち、Publish Subjectは持たないという特徴があります。 なので僕はウィジェット間で状態を保持したいときはBehavior Subject。 ボタンなどでアクションの発生を伝えたいときはPublish Subjectという使い方をしています。 あくまで僕の使い方なので正しいかどうかは分かりませんが、参考になると嬉しいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問