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

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

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

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

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

2591閲覧

Providerを使用してもnotifierでリビルドされない

ringoringogogo

総合スコア15

Flutter

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

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

1クリップ

投稿2021/05/20 12:40

添付のようにURLからアイキャッチ画像とタイトルを取得して表示させる画面を作成しています。
イメージ説明

今回の問題点としては、ゴミ箱マークをタップした時にデータから削除され、動的に表示されているリストからも見えないようにリビルドしたいのですが、Providerの使い方を理解できていないようで表示が変わりません・・。

大変恐縮ですが、原因がわかる方がいらっしゃいましたらお力添えいただけませんでしょうか。

main.dart

Dart

1import 'package:flutter/material.dart'; 2import 'cliplist_model.dart'; 3import 'package:url_launcher/url_launcher.dart'; 4import 'package:shared_preferences/shared_preferences.dart'; 5import 'package:provider/provider.dart'; 6 7void main() { 8 runApp( 9 ChangeNotifierProvider<ClipListModel>( 10 create: (context) => ClipListModel(), 11 child:MyApp() 12 )); 13} 14 15class MyApp extends StatelessWidget { 16 // This widget is the root of your application. 17 18 Widget build(BuildContext context) { 19 savedata(); 20 21 return MaterialApp( 22 title: 'Flutter Demo', 23 theme: ThemeData( 24 primarySwatch: Colors.blue, 25 ), 26 home: ClipScreen(), 27 ); 28 } 29} 30class ClipScreen extends StatelessWidget { 31 const ClipScreen({Key key}) : super(key: key); 32 33 34 Widget build(BuildContext context) { 35 return Scaffold( 36 appBar: AppBar( 37 title: Text("クリップリスト"), 38 ), 39 body: Center( 40 child: Container( 41 child: FutureBuilder<List<PageData>>( 42 future: Provider.of<ClipListModel>(context, listen: false).request(), 43 builder: (context, dataSnapshot) { 44 if (dataSnapshot.connectionState == 45 ConnectionState.waiting) { 46 // 非同期処理未完了 = 通信中 47 return Center( 48 child: CircularProgressIndicator(), 49 ); 50 } 51 52 if (dataSnapshot.error != null) { 53 // エラー 54 return Center( 55 child: Text('エラーが発生しました。一度アプリを終了し再度起動してください') 56 ); 57 } 58 59 if (dataSnapshot.data.length == 0) { 60 return Center( 61 child: Text('データがありません') 62 ); 63 } 64 return clipListContents(dataSnapshot.data); 65 }))) 66 ); 67 } 68} 69 70 71 72void savedata()async{ 73 SharedPreferences saveprefs = await SharedPreferences.getInstance(); 74 List<String> tmpData = ["https://qiita.com/","https://tenki.jp/","https://news.yahoo.co.jp/"]; 75 await saveprefs.setStringList("CLIPLIST", tmpData); 76 77} 78 79 80Widget clipListContents(List<PageData> cliplistdata) { 81 return ListView.builder( 82 physics: AlwaysScrollableScrollPhysics(), 83 itemCount: cliplistdata.length, 84 itemBuilder: (lctx, index) => 85 Consumer<ClipListModel>( 86 builder: (context, clipdata, child) { 87 return Padding( 88 padding: const EdgeInsets.only( 89 right: 8.0, left: 8.0), 90 child: InkWell( 91 onTap: () { 92 launch(cliplistdata[index].url); 93 }, 94 child: Row( 95 mainAxisAlignment: MainAxisAlignment 96 .spaceBetween, 97 children: <Widget>[ 98 Image.network( 99 cliplistdata[index].image, 100 height: 100.0, width: 100.0), 101 new Expanded( 102 child: new Column( 103 crossAxisAlignment: 104 CrossAxisAlignment.start, 105 children: <Widget>[ 106 Padding( 107 padding: 108 EdgeInsets.only( 109 left: 8.0), 110 child: Text( 111 (cliplistdata 112 [index] 113 .sitename), 114 style: 115 TextStyle( 116 fontSize: 18)), 117 ), 118 Padding( 119 padding: 120 EdgeInsets.only( 121 left: 12.0), 122 child: Text( 123 cliplistdata 124 [index] 125 .title, 126 style: TextStyle( 127 color: Colors 128 .black38)), 129 ) 130 ])), 131 IconButton( 132 icon: const Icon(Icons.delete), 133 onPressed: () { 134 ClipListModel().trash( 135 cliplistdata[index]); 136 showDialog( 137 context: lctx, 138 builder: (_) { 139 return AlertDialog( 140 content: Text( 141 "クリップリストから削除します"), 142 actions: <Widget>[ 143 FlatButton( 144 onPressed: () => 145 Navigator 146 .of(lctx) 147 .pop //OKボタンをクリックしてもダイアログが閉じないので一旦OKを消している 148 ) 149 ], 150 ); 151 }, 152 ); 153 }, 154 ), 155 ]), 156 ) 157 ); 158 }), 159 ); 160} 161 162

cliplist_model.dart

dart

1import 'package:flutter/material.dart'; 2import 'package:flutter/foundation.dart'; 3import 'package:shared_preferences/shared_preferences.dart'; 4import 'package:universal_html/driver.dart' as driver; 5import 'package:http/http.dart' as http; 6import 'package:html/parser.dart'; 7import 'package:http/http.dart'; 8 9class ClipListModel extends ChangeNotifier { 10 List<String> cliplist = []; 11 List<String> bookmark = []; 12 List<PageData> pagedataList = []; 13 14 Future<List<PageData>> request() async { 15 if (pagedataList != null) { 16 pagedataList.removeRange(0, pagedataList.length); 17 } 18 SharedPreferences prefs = await SharedPreferences.getInstance(); 19 cliplist = prefs.getStringList("CLIPLIST"); 20 if(cliplist==null){ 21 cliplist=[]; 22 } 23 24 for (int i = 0; i < cliplist.length; i++) { 25 PageData tmpPageData = new PageData(); 26 tmpPageData = await fetch(cliplist[i]); 27 pagedataList.add(tmpPageData); 28 } 29 notifyListeners(); 30 return pagedataList; 31 } 32 33 Future<void> trash(deletePageData) async { 34 if(pagedataList!= null){ 35 pagedataList.remove(deletePageData); 36 } 37 38 SharedPreferences prefs = await SharedPreferences.getInstance(); 39 cliplist = prefs.getStringList("CLIPLIST"); 40 cliplist.remove(deletePageData.url); 41 await prefs.setStringList("CLIPLIST", cliplist); 42 43 notifyListeners(); 44 } 45 46 _validateUrl(String url) { 47 if (url?.startsWith('http://') == true || 48 url?.startsWith('https://') == true) { 49 return url; 50 } 51 else { 52 return 'http://$url'; 53 } 54 } 55 56 Future<PageData> fetch(url) async { 57 final client = Client(); 58 final response = await client.get(_validateUrl(url)); 59 final document = parse(response.body); 60 61 PageData tmpPageData = new PageData(); 62 tmpPageData.url = url; 63 64 var elements = document.getElementsByTagName('meta'); 65 //final linkElements = document.getElementsByTagName('link'); 66 67 for (int i = 0; i < elements.length; i++) { 68 if (elements[i].attributes['property'] == 'og:site_name') { 69 tmpPageData.sitename = elements[i].attributes['content']; 70 continue; 71 } 72 if (elements[i].attributes['property'] == 'og:title') { 73 tmpPageData.title = elements[i].attributes['content']; 74 continue; 75 } 76 if (elements[i].attributes['property'] == 'og:image') { 77 tmpPageData.image = elements[i].attributes['content']; 78 continue; 79 } 80 } 81 return tmpPageData; 82 } 83 84} 85 86 87class PageData{ 88 String sitename; 89 String title; 90 String image; 91 String url; 92} 93

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

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

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

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

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

guest

回答1

0

ベストアンサー

dart

1Provider.of<ClipListModel>(context, listen: false).request();

のところを

dart

1Provider.of<ClipListModel>(context).request();

にしてみて下さい。
ちなみに”listen: false”をつけると、「notifyListeners();を実行してもリビルドしないでくださいね」という意味になるので、注意してください。

投稿2021/07/29 08:08

編集2021/07/29 08:10
children

総合スコア89

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

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

ringoringogogo

2021/08/05 06:21

ご回答ありがとうございます!!なるほど・・・承知いたしました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問