問題点
以下のようなプログラムをflutter firebase provderを使って作っています。
⓵でCardをタップしたらタップされたドキュメントIDを使い⓶でデータを取得し③で表示したいのですが、コンソールには出力できるのですが、③のページに表示できません。
ご教授よろしくお願いいたします。
コード
①
dart
1 body: Consumer<TeaProvider>(builder: (context, model, child) { 2 final todoList = model.todoList; 3 return ListView( 4 children: todoList 5 .map( 6 (todo) => Card( 7 margin: const EdgeInsets.only(left:20,right:20,top:5,bottom:5), 8 elevation: 3, 9 child: InkWell( 10 onTap: ()async{ 11 await ViewBook(context , model , todo); 12 Navigator.push( 13 context, 14 MaterialPageRoute(builder: (context) => ViewPage())); 15 }, 16 child: Container( 17 height: MediaQuery.of(context).size.height * 0.15, 18 child: Row( 19 mainAxisAlignment: MainAxisAlignment.start, 20 children: [ 21 Column( 22 mainAxisAlignment: MainAxisAlignment.spaceAround, 23 crossAxisAlignment: CrossAxisAlignment.center, 24 children: [ 25 Padding( 26 padding: const EdgeInsets.only(right:10.0,left:10.0), 27 child: Container( 28 width: 50, 29 height: 50, 30 decoration: BoxDecoration( 31 color: Colors.red, 32 shape: BoxShape.circle 33 ), 34 ), 35 ), 36 Padding( 37 padding: const EdgeInsets.only( 38 right: 10.0, left: 10.0), 39 child: Text(todo.name, 40 ), 41 ), 42 ], 43 ), 44 Container( 45 height: 80, 46 child: VerticalDivider( 47 color: Colors.black54, 48 ) 49 ), 50 Flexible( 51 child: Column( 52 crossAxisAlignment: CrossAxisAlignment.start, 53 mainAxisAlignment: MainAxisAlignment.start, 54 children: [ 55 Padding( 56 padding: const EdgeInsets.only(bottom:4.0), 57 child: Text(todo.recipe, 58 overflow: TextOverflow.ellipsis, 59 maxLines: 2, 60 style: TextStyle( 61 fontWeight: FontWeight.bold, 62 fontSize: 17 63 ),), 64 ), 65 Text(todo.title, 66 overflow: TextOverflow.ellipsis, 67 maxLines: 2, 68 ), 69 Text( '調理時間:'+todo.time+'min') 70 ], 71 ), 72 ) 73 ], 74 ) 75 ), 76 ), 77 78 ), 79 ).toList(), 80 ); 81 }), 82Future ViewBook(BuildContext context , TeaProvider model , Todo todo) async { 83 84 await model.getTapmodel(todo); 85}
⓶
dart
1※抜粋しています 2class TeaProvider extends ChangeNotifier { 3 Future getTapmodel(Todo todo) async{ 4 final snapshoted = await FirebaseFirestore.instance 5 .collection('todoList') 6 .doc(todo.documentID) 7 .get(); 8 notifyListeners(); 9 viewText = snapshoted['title']; 10 viewTodo = snapshoted['name']; 11 viewItem = snapshoted['recipe']; 12 viewTime = snapshoted['time']; 13 viewName = snapshoted['material']; 14 print(viewText); 15 print(viewTime); 16 print(viewTodo); 17 print(viewName); 18 print(viewItem); 19 notifyListeners(); 20 } 21 String viewText; 22 String viewTodo; 23 String viewItem; 24 String viewTime; 25 String viewName; 26 27}
⓷
dart
1class ViewPage extends StatelessWidget { 2 3 4 Widget build(BuildContext context) { 5 return ChangeNotifierProvider<TeaProvider>( 6 create: (_) => TeaProvider(), 7 child: Scaffold( 8 appBar: AppBar( 9 backgroundColor: Colors.green, 10 title: Text('Tea App'), 11 centerTitle: true, 12 ), 13 body: Consumer<TeaProvider>(builder: (context, model, child) { 14 return Container( 15 child: Center( 16 child: Column( 17 children: [ 18 Text(model.viewItem??'データなし'), 19 Text(model.viewName??'データなし'), 20 Text(model.viewTodo??'データなし'), 21 Text(model.viewTime??'データなし'), 22 Text(model.viewText??'データなし'), 23 ] 24 ), 25 ) 26 ); 27 }, 28 ) 29 ), 30 ); 31 } 32}
dart
1class Todo { 2 Todo(DocumentSnapshot doc){ 3 this.documentID = doc.id; 4 this.title = doc['title']; 5 this.recipe = doc['recipe']; 6 this.material = doc['material']; 7 this.time = doc['time']; 8 this.name = doc['name']; 9 } 10 String documentID; 11 String time; 12 String material; 13 String recipe; 14 String title; 15 String name; 16}
ぱっと見ですがgetTapmodelの定義自体に問題はなさそうなので、それを実際に発火させているところが見たいです!
コメントありがとうございます!
①のコードの最後で発火させています。
自分も定義は間違っていないと思ったんですけど表示されないんですよね
修正ありがとうございます!
今はViewPageで
ChangeNotifierProvider<TeaProvider>(
create: (_) => TeaProvider(),
child:Scaffold
--------------------------------------
を書かれていると思うのですが、これをもうちょい上のMyAppで
MaterialApp(
home: ChangeNotifierProvider<TeaProvider>(
create: (_) => TeaProvider(),
child: MyHomePage(),
),
);
みたいな風に書いてみて下さい。
修正してみたのですが、表示されませんでした。
先ほど教えていただいた、MyAppというのはmain.dartで修正するということですよね?
そうです、正常に動いてないようで申し訳ないです。。
一応確認させていただきたいのですが、ViewPageの方のChangenotifierProviderは消していただけたでしょうか?
一応私が先程のような修正をお願いしたのは、Navigator.pushする際にProviderが適切に渡せていない可能性があると思ったからです。詳しくは下記のリンクをみていただければと思います。
https://stackoverflow.com/questions/59576495/flutter-provider-nested-navigation
今気付いたのですが、①でも③でもChangenotifierProviderのcreateでインスタンスを生成してますよね?
①で作成したインスタンスと③で作成したインスタンスが異なるのが原因だと思います。
ChangeNotifierProviderでインスタンスを生成するのは一度だけでいいので、main.dart以外でChangeNotifierProviderを使っているところがあれば、全部消してみてください。
l
class ViewPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<TeaProvider>(
/*create: (_) => TeaProvider(),*/ ←これでいいのですか?
child: MaterialApp(
home : Scaffold(
appBar: AppBar(
backgroundColor: Colors.green,
title: Text('Tea App'),
centerTitle: true,
),
body: Consumer<TeaProvider>(builder: (context, model, child) {
return Container(
child: Center(
child: Column(
children: [
Text(model.viewItem??'データなし'),
Text(model.viewName??'データなし'),
Text(model.viewTodo??'データなし'),
Text(model.viewTime??'データなし'),
Text(model.viewText??'データなし'),
]
),
)
);
},
)
),
),
);
}
}
とんでもないです。
create: (_)=>TeaProvider()のタイミングです。
こちらの記事が参考になるかと思います。
https://blog.dalt.me/1903
ちょっとちがいますね。
MaterialAppもChangeNotifierProviderもmain.dartにのみ書いてください。
それ以下のページでProviderの値にアクセスするときは、ChangeNotifierProviderを使わずにConsumerのみを使うようにしてください。
これで良いのでしょうか?
Widget build(BuildContext context) {
return MaterialApp(
home:MultiProvider(
providers: [
ChangeNotifierProvider<LogoinpModel>(
create: (_) => LogoinpModel()),
ChangeNotifierProvider<TeaProvider>(
create: (_) => TeaProvider()..getTeaListRealtime()),
ChangeNotifierProvider<SignUpModel>(
create: (_) => SignUpModel()),
],
---------------------------
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
drawer: NavDrawer(),
appBar: AppBar(
backgroundColor: Colors.green,
title: Text('Tea App'),
centerTitle: true,
actions: [
Padding(
padding: EdgeInsets.only(right: 15),
child: Icon(Icons.expand_more_sharp),
),
],
),
Could not find the correct Provider<TeaProvider> above this Consumer<TeaProvider> Widget
上記のようなエラーgが出てしまいます
そのエラーが出るのはどのタイミングですか?
また、MultiProviderのchildには何を与えていますか?
main.dartではログインページを入れていてログインが成功するとエラーが発生し赤い画面になります。
MultiProviderのchildにはログインページのみで画面遷移でほかのページに移動しています。
void main() async{
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home:MultiProvider(
providers: [
ChangeNotifierProvider<LogoinpModel>(
create: (_) => LogoinpModel()),
ChangeNotifierProvider<TeaProvider>(
create: (_) => TeaProvider()..getTeaListRealtime()),
ChangeNotifierProvider<SignUpModel>(
create: (_) => SignUpModel()),
],
child:MyLogin(),
),
);
}
}
class MyLogin extends StatefulWidget {
@override
_MyLoginState createState() => _MyLoginState();
}
class _MyLoginState extends State<MyLogin> {
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Consumer<LogoinpModel>(
builder: (context, model, child){
return Column(
children: [
Container(
height: MediaQuery.of(context).size.height * 0.7,
width: MediaQuery.of(context).size.width.....
という感じです
情報提供ありがとうございます!
でしたら、main関数内のMyAppをMultiProviderで包む形で書きかえてみてください。
大体↓みたいな感じです。
void main() {
runApp(MutiProvider(省略), child: MyApp()));
}
できました!!!!!!
一週間くらいここで詰まっていたのでほんとに助かりました!
何から何まで今日一日本当にありがとうございました。
自力で解決できるように勉強していきます( ;∀;)
ベストアンサーを付けたいので回答のほうに書いてもらってよろしいでしょうか?
解決できたようで良かったです!
お役に立てて光栄です。
回答1件
あなたの回答
tips
プレビュー

