🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Flutter

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

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

Q&A

解決済

2回答

1609閲覧

[Flutter]再起動後も同じ画面を表示させたい

ts21

総合スコア32

Flutter

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

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2021/02/25 14:56

編集2021/02/27 03:23

前提・実現したいこと

FlutterでWebviewを用いたアプリケーションを開発しています。

setting画面とview画面があり、以下の3つを実装したいのですが、[3]が実装できていません。

[1]setting画面からview画面に遷移する
[2]setting画面で入力したURLをview画面で表示させたい
[3]その表示させた画面は再起動後もview画面で表示される

###実装方法
まず、setting画面の入力フォームにWebviewで表示させたいwebページのURLを入力します。
下の画面がsetting画面で、このときtwitterのURLを入力しています。
イメージ説明

setting画面で受け取ったURLは一度SharedPreferencesで保存(save)して、view画面で受け取ります。

view画面では、下のようにtwitterが確認できました

イメージ説明

しかしエミュレータを再起動するとview画面にtwitterの画面が表示されず、[3]の実装ができていないことがわかりました。

setting画面のソースコード

dart

1 2import 'package:flutter/material.dart'; 3import 'view.dart'; 4import 'package:shared_preferences/shared_preferences.dart'; 5import 'Widgets/drawer.dart'; 6 7class SettingScreen extends StatefulWidget { 8 static const routeName = '/setting'; 9 10 11 State<StatefulWidget> createState() => SettingScreenState(); 12} 13 14class SettingScreenState extends State<SettingScreen> { 15 static const routeName = '/setting'; 16 final _formKey = GlobalKey<FormState>(); 17 String input; 18 19 void _save(String url) async { 20 SharedPreferences pref = await SharedPreferences.getInstance(); 21 pref.setString('url', url); 22 } 23 24 25 Widget build(BuildContext context) { 26 return Scaffold( 27 drawer: DrawerScreen(), 28 body: Form( 29 key: _formKey, 30 child: Column( 31 crossAxisAlignment: CrossAxisAlignment.center, 32 children: [ 33 Padding( 34 padding: const EdgeInsets.all(16.0), 35 child: Container( 36 child: Text('setting'), 37 ), 38 ), 39 TextFormField( 40 decoration: const InputDecoration( 41 labelText: 'URL *', 42 ), 43 onSaved: (String value) { 44 input = value; 45 }, 46 ), 47 Padding( 48 padding: const EdgeInsets.symmetric(vertical: 16.0), 49 child: _sendButton(context), 50 ), 51 ], 52 ), 53 )); 54 } 55 56 Widget _sendButton(BuildContext context) { 57 return RaisedButton( 58 onPressed: () { 59 this._formKey.currentState.save(); 60 if (input == "") { 61 _showDialog(context); 62 } else { 63 _save(input); 64 Navigator.of(context).push(MaterialPageRoute( 65 builder: (context) => ViewScreen(url: input), 66 fullscreenDialog: true)); 67 } 68 }, 69 child: Text('connect'), 70 ); 71 } 72 73 void _showDialog(BuildContext context) { 74 showDialog( 75 context: context, 76 builder: (BuildContext context) { 77 return AlertDialog( 78 title: Text("エラー"), 79 content: Text("指定されたURLに接続できません"), 80 actions: <Widget>[ 81 FlatButton( 82 child: Text("OK"), 83 onPressed: () { 84 Navigator.of(context).pop(); 85 }, 86 ), 87 ], 88 ); 89 }); 90 } 91} 92

###view画面のソースコード

dart

1import 'package:assets_audio_player/assets_audio_player.dart'; 2import 'package:flutter/material.dart'; 3import 'package:webview_flutter/webview_flutter.dart'; 4import 'package:shared_preferences/shared_preferences.dart'; 5import 'Widgets/drawer.dart'; 6 7class ViewScreen extends StatefulWidget { 8 static const routeName = '/view'; 9 final String url; 10 11 ViewScreen({Key key, this.url}) : super(key: key); 12 13 14 State<StatefulWidget> createState() => ViewScreenState(); 15} 16 17class ViewScreenState extends State<ViewScreen> { 18 Future<String> _future; 19 String _view = "message"; 20 21 Future<String> _load() async { 22 SharedPreferences pref = await SharedPreferences.getInstance(); 23 _view = pref.getString('url') ?? ''; 24 return Future.value(_view); 25 } 26 27 28 void initState() { 29 super.initState(); 30 _future = _load(); 31 } 32 33 34 Widget build(BuildContext context) { 35 return Scaffold( 36 drawer: DrawerScreen(), 37 body: FutureBuilder( 38 future: _future, 39 builder: (context, AsyncSnapshot<String> snapshot) { 40 switch (snapshot.connectionState) { 41 case ConnectionState.none: 42 return Text('none'); 43 case ConnectionState.waiting: 44 return Center(child: CircularProgressIndicator()); 45 case ConnectionState.active: 46 return Text(''); 47 case ConnectionState.done: 48 if (snapshot.hasError) { 49 return Text( 50 '${snapshot.error}', 51 style: TextStyle(color: Colors.red), 52 ); 53 } else { 54 return WebView( 55 initialUrl: _view, 56 javascriptMode: JavascriptMode.unrestricted, 57 javascriptChannels: Set.from([ 58 JavascriptChannel( 59 name: "getData", 60 onMessageReceived: (JavascriptMessage result) { 61 if (result.message == "play sound") { 62 AssetsAudioPlayer().open( 63 Audio("assets/announce.wav"), 64 ); 65 } 66 }), 67 ]), 68 ); 69 } 70 } 71 })); 72 } 73} 74 75Future<void> main() async { 76 WidgetsFlutterBinding.ensureInitialized(); 77 SharedPreferences pref = await SharedPreferences.getInstance(); 78 await pref.setString('url', ''); 79 runApp(MyApp()); 80} 81 82class MyApp extends StatelessWidget { 83 84 Widget build(BuildContext context) { 85 return MaterialApp( 86 home: ViewScreen(), 87 ); 88 } 89} 90

[1]~[2]の実装自体がよくないのでしょうか?
どなたかご指摘ください

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

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

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

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

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

guest

回答2

0

自己解決

次のように、View画面でsaveとloadを実行することで解決しました。
初期化のinitStateにも問題がありました

dart

1import 'package:assets_audio_player/assets_audio_player.dart'; 2import 'package:flutter/material.dart'; 3import 'package:webview_flutter/webview_flutter.dart'; 4import 'package:shared_preferences/shared_preferences.dart'; 5import 'Widgets/drawer.dart'; 6 7class ViewScreen extends StatefulWidget { 8 static const routeName = '/home'; 9 String url; 10 11 ViewScreen({Key key, this.url}) : super(key: key); 12 13 14 State<StatefulWidget> createState() => ViewScreenState(); 15} 16 17class ViewScreenState extends State<ViewScreen> { 18 Future<String> _future; 19 String _view = "message"; 20 21 Future<String> _load() async { 22 SharedPreferences prefs = await SharedPreferences.getInstance(); 23 _view = prefs.getString('url') ?? 'https://www.yahoo.co.jp/'; 24 return Future.value(_view); 25 } 26 27 Future<String> _save() async { 28 setState(() { 29 _setPrefItems(); 30 }); 31 } 32 33 _setPrefItems() async { 34 SharedPreferences prefs = await SharedPreferences.getInstance(); 35 if (widget.url != null) { 36 prefs.setString('url', widget.url); 37 } 38 } 39 40 41 void initState() { 42 super.initState(); 43 _future = _save(); 44 _future = _load(); 45 } 46 47 48 Widget build(BuildContext context) { 49 return Scaffold( 50 drawer: DrawerScreen(), 51 body: FutureBuilder( 52 future: _future, 53 builder: (context, AsyncSnapshot<String> snapshot) { 54 switch (snapshot.connectionState) { 55 case ConnectionState.none: 56 return Text('none'); 57 case ConnectionState.waiting: 58 return Center(child: CircularProgressIndicator()); 59 case ConnectionState.active: 60 return Text(''); 61 case ConnectionState.done: 62 if (snapshot.hasError) { 63 return Text( 64 '${snapshot.error}', 65 style: TextStyle(color: Colors.red), 66 ); 67 } else { 68 return WebView( 69 initialUrl: _view, 70 javascriptMode: JavascriptMode.unrestricted, 71 javascriptChannels: Set.from([ 72 JavascriptChannel( 73 name: "getData", 74 onMessageReceived: (JavascriptMessage result) { 75 if (result.message == "play sound") { 76 AssetsAudioPlayer().open( 77 Audio("assets/announce.wav"), 78 ); 79 } 80 }), 81 ]), 82 ); 83 } 84 } 85 })); 86 } 87} 88 89Future<void> main() async { 90 WidgetsFlutterBinding.ensureInitialized(); 91 runApp(MyApp()); 92} 93 94class MyApp extends StatelessWidget { 95 96 Widget build(BuildContext context) { 97 return MaterialApp( 98 home: HomeScreen(), 99 ); 100 } 101} 102

投稿2021/03/01 17:39

ts21

総合スコア32

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

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

0

SharedPreferencesには保存されているもの、setting画面から自動的にview画面に遷移しないということが問題なのではないでしょうか。
setting画面のソースコードで、SharedPreferencesに値がある場合の条件式を記述し、SharedPreferencesにURLが残っている場合は自動的にview画面へ遷移するように設定したらどうでしょうか。

投稿2021/02/28 08:40

Rassy

総合スコア44

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問