実現したいこと
●あるページから別ページのリストビューを自動的に更新したいです
●本サイトにて以前にも似たような質問をして回答を頂いていますが
階層が深く(複数のクラス/ウィジェットを経由)すると対応が難しい事がわかりましたのでProviderを使う事にしました。
前提
●メインページにBottomAppBar等を使用したアプリを作っています
→アプリ起動後の初期画面はPage1を表示
→Page1のデータ取得にはData2Notifierを使用
●BottomAppBarの中央にくるIconButtonからページ2に移動します
→Page2はDBにデータを登録する処理
→Page1はDBに登録されたデータを取得してリストに表示する処理
発生している問題
● notifyListenersでデータを送信し、Consumerで変更データを受信すると聞いていますが
冒頭の通りリストの自動更新が動きません
●検索で上位に上がってくるサイトを参考にしながら確認しましたがイマイチ原因がわかりません
誤っている部分や、そもそも考え方が誤っている部分が多分に含まれていると思いますのでご指摘いただけないでしょうか?
該当のソースコード
main
1void main() { 2 runApp( 3 MultiProvider( 4 providers: [ 5 ChangeNotifierProvider<Data1Notifier>(create: (context) => Data1Notifier()), 6 ChangeNotifierProvider<Data2Notifier>(create: (context) => Data2Notifier()), 7 ChangeNotifierProvider<Data3Notifier>(create: (context) => Data3Notifier()), 8 ], 9 child: MyApp(), 10 ), 11 ); 12} 13 14class MyApp extends StatelessWidget { 15 ~省略~ 16} 17 18 19class MainPage extends StatefulWidget { 20 MainPage({Key? key}) : super(key: key); 21 22 @override 23 _MainPageState createState() => _MainPageState(); 24} 25 26class _MainPageState extends State<MainPage> with WidgetsBindingObserver { 27 int _selectedIndex = 0; 28 late PageController _pageController; 29 30 @override 31 Widget build(BuildContext context) { 32 initializeDateFormatting('ja'); 33 34 return Scaffold( 35 appBar: AppBar( 省略 ), 36 body: PageView( 37 controller: _pageController, 38 onPageChanged: (index) { 39 setState(() => _selectedIndex = index); 40 }, 41 children: _pageList), 42 bottomNavigationBar: BottomAppBar( 43 height: 120.w, 44 child: Container( 45 width: 600.w, 46 child: Row( 47 mainAxisAlignment: MainAxisAlignment.spaceBetween, 48 children: [ 49 Container(width: 30), 50 IconButton( 51 onPressed: () { 52 _selectedIndex = 0; 53 _pageController.animateToPage(_selectedIndex, duration: Duration(seconds: 1), curve: Curves.easeInOutCubic); 54 }, 55 icon: Icon(Icons.account_circle_rounded, size: 60.sp, color: white), 56 ), 57 Spacer(), 58 IconButton( 59 onPressed: () async { 60 Navigator.of(context).push(PageRouteBuilder( 61 pageBuilder: (context, animation, secondaryAnimation) => Page1(), 62 transitionsBuilder: (context, animation, secondaryAnimation, child) { 63 final Animatable<Offset> tween = Tween(begin: Offset(0.0, 1.0), end: Offset.zero).chain(CurveTween(curve: Curves.easeInOut)); 64 final Animation<Offset> offsetAnimation = animation.drive(tween); 65 return SlideTransition(position: offsetAnimation, child: child); 66 })); 67 }, 68 icon: Icon(Icons.add, size: 60.sp, color: white), 69 ), 70 Spacer(), 71 IconButton( 72 onPressed: () { 73 _selectedIndex = 1; 74 _pageController.animateToPage(_selectedIndex, duration: Duration(seconds: 1), curve: Curves.easeInOutCubic); 75 }, 76 icon: Icon(Icons.business, size: 60.sp, color: white), 77 ), 78 Container(width: 30), 79 ], 80 ), 81 ), 82 ), 83 ); 84 }
Page1
1class Page1 extends StatefulWidget { 2 const Page1({Key? key}) : super(key: key); 3 4 @override 5 State<Page1> createState() => _Page1State(); 6} 7 8class _Page1State extends State<Page1> { 9 @override 10 Widget build(BuildContext context) { 11 final Data2 = Provider.of<Data2Notifier>(context, listen: false); 12 final Data1 = Provider.of<Data1Notifier>(context); 13 14 return Scaffold( 15 body: FutureBuilder( 16 future: Data2.getData(context), 17 builder: (context, snapshot) { 18 if (snapshot.connectionState == ConnectionState.waiting) { 19 return _loading(); //データロード中の場合 20 } 21 22 if (snapshot.hasError) { 23 return errUI(context); //エラーが起きた場合 24 } 25 26 if (Data2.items.length == 0) { 27 return _noData(context); //データ件数ゼロの場合 28 } 29 30 return Consumer<Data2Notifier>( 31 builder: (context, value, child) { 32 return _cardList(context, Data1,value.data); //データ件数1以上存在の場合 33 }, 34 ); 35 }), 36 ); 37 } 38}
Data2Notifier
1class Data2Notifier extends ChangeNotifier { 2 List items = []; 3 4 Future getData(context) async { 5 final Data1 = Provider.of<Data1Notifier>(context,listen: false); 6 Map<String, dynamic> postData = {"client_id": Data.code}; 7 8 final response = await http.post( 9 Uri.parse("${Data1.url}/dummy/dummy"), 10 headers: { 11 "Content-Type": "application/json", 12 }, 13 body: json.encode(postData), 14 ); 15 16 print(response.statusCode); 17 if (response.statusCode == 200) { 18 var result = GetExistData.fromJson(jsonDecode(response.body)); 19 items = result.items; 20 } else { 21 throw "error"; 22 } 23 } 24 25 notifyListeners(); 26} 27 28class GetExistData { 29 final List items; 30 31 GetExistData({required this.items}); 32 33 factory GetExistData.fromJson(Map<String, dynamic> json) => GetExistData(items: json['data']); 34}
あなたの回答
tips
プレビュー