質問編集履歴

1

追記

2021/02/27 03:23

投稿

ts21
ts21

スコア32

test CHANGED
@@ -1 +1 @@
1
- [Flutter]SharedPreferencesでWebview保持したい
1
+ [Flutter]再起動後も同じ画面表示させたい
test CHANGED
@@ -1,37 +1,253 @@
1
1
  ### 前提・実現したいこと
2
2
 
3
- アプリを開いた段階で、過去に閲覧したwebページをそのまま表示させたいです。
3
+
4
-
4
+
5
- その前段階としてWebviewの実装に手間取っています。
5
+ FlutterでWebviewを用いたアプリケーションを開発しています。
6
+
7
+
8
+
6
-
9
+ setting画面とview画面があり、以下の3つを実装したいのですが、[3]が実装できていません。
7
-
8
-
10
+
11
+
12
+
9
- setting画面view画面に遷移しま
13
+ [1]setting画面からview画面に遷移す
14
+
10
-
15
+ [2]setting画面で入力したURLをview画面で表示させたい
16
+
17
+ [3]その表示させた画面は再起動後もview画面で表示される
18
+
19
+
20
+
21
+ ###実装方法
22
+
11
- 最初にsetting画面にWebviewで表示たいURLを入力します。
23
+ まず、setting画面の入力フォームにWebviewで表示させたいwebページのURLを入力します。
12
-
24
+
13
- connectボタンを押す、view画面にURLをパラメータとして画面遷移します。
25
+ 下の画面がsetting画面で、このきtwitterのURLを入力してます。
26
+
14
-
27
+ ![イメージ説明](9e30287bb74c5acb1ea3c0d31c8b1ca3.png)
28
+
29
+
30
+
31
+ setting画面で受け取ったURLは一度`SharedPreferences`で保存(save)して、view画面で受け取ります。
32
+
33
+
34
+
35
+ view画面では、下のようにtwitterが確認できました
36
+
37
+
38
+
15
- ![イメージ説明](25f9af793eb72813b23e8171fa503316.png)
39
+ ![イメージ説明](d1fd19c4a255289c09df9604055f1d1e.png)
16
-
17
-
18
-
40
+
41
+
42
+
19
- view画面では、こURLのページを表示するはですが画像のように真っ白な画面になっていま
43
+ しかしエミュレータを再起動するとview画面にtwitter画面が表示されず、[3]実装ができていないことがわかりした
20
-
21
- ![イメージ説明](0dfbd75e54b8abdc6ac59520f9b99e5b.png)
44
+
22
-
23
- appbarのテキストから、パラメータ自体は受け取っていることがわかります。
45
+
24
-
25
-
26
-
46
+
27
- ### 該当のソースコード
47
+ ### setting画面のソースコード
28
-
29
- view画面のview.dartは以下のようにコーディングしました。
48
+
49
+
30
50
 
31
51
  ```dart
32
52
 
53
+
54
+
33
55
  import 'package:flutter/material.dart';
34
56
 
57
+ import 'view.dart';
58
+
59
+ import 'package:shared_preferences/shared_preferences.dart';
60
+
61
+ import 'Widgets/drawer.dart';
62
+
63
+
64
+
65
+ class SettingScreen extends StatefulWidget {
66
+
67
+ static const routeName = '/setting';
68
+
69
+
70
+
71
+ @override
72
+
73
+ State<StatefulWidget> createState() => SettingScreenState();
74
+
75
+ }
76
+
77
+
78
+
79
+ class SettingScreenState extends State<SettingScreen> {
80
+
81
+ static const routeName = '/setting';
82
+
83
+ final _formKey = GlobalKey<FormState>();
84
+
85
+ String input;
86
+
87
+
88
+
89
+ void _save(String url) async {
90
+
91
+ SharedPreferences pref = await SharedPreferences.getInstance();
92
+
93
+ pref.setString('url', url);
94
+
95
+ }
96
+
97
+
98
+
99
+ @override
100
+
101
+ Widget build(BuildContext context) {
102
+
103
+ return Scaffold(
104
+
105
+ drawer: DrawerScreen(),
106
+
107
+ body: Form(
108
+
109
+ key: _formKey,
110
+
111
+ child: Column(
112
+
113
+ crossAxisAlignment: CrossAxisAlignment.center,
114
+
115
+ children: [
116
+
117
+ Padding(
118
+
119
+ padding: const EdgeInsets.all(16.0),
120
+
121
+ child: Container(
122
+
123
+ child: Text('setting'),
124
+
125
+ ),
126
+
127
+ ),
128
+
129
+ TextFormField(
130
+
131
+ decoration: const InputDecoration(
132
+
133
+ labelText: 'URL *',
134
+
135
+ ),
136
+
137
+ onSaved: (String value) {
138
+
139
+ input = value;
140
+
141
+ },
142
+
143
+ ),
144
+
145
+ Padding(
146
+
147
+ padding: const EdgeInsets.symmetric(vertical: 16.0),
148
+
149
+ child: _sendButton(context),
150
+
151
+ ),
152
+
153
+ ],
154
+
155
+ ),
156
+
157
+ ));
158
+
159
+ }
160
+
161
+
162
+
163
+ Widget _sendButton(BuildContext context) {
164
+
165
+ return RaisedButton(
166
+
167
+ onPressed: () {
168
+
169
+ this._formKey.currentState.save();
170
+
171
+ if (input == "") {
172
+
173
+ _showDialog(context);
174
+
175
+ } else {
176
+
177
+ _save(input);
178
+
179
+ Navigator.of(context).push(MaterialPageRoute(
180
+
181
+ builder: (context) => ViewScreen(url: input),
182
+
183
+ fullscreenDialog: true));
184
+
185
+ }
186
+
187
+ },
188
+
189
+ child: Text('connect'),
190
+
191
+ );
192
+
193
+ }
194
+
195
+
196
+
197
+ void _showDialog(BuildContext context) {
198
+
199
+ showDialog(
200
+
201
+ context: context,
202
+
203
+ builder: (BuildContext context) {
204
+
205
+ return AlertDialog(
206
+
207
+ title: Text("エラー"),
208
+
209
+ content: Text("指定されたURLに接続できません"),
210
+
211
+ actions: <Widget>[
212
+
213
+ FlatButton(
214
+
215
+ child: Text("OK"),
216
+
217
+ onPressed: () {
218
+
219
+ Navigator.of(context).pop();
220
+
221
+ },
222
+
223
+ ),
224
+
225
+ ],
226
+
227
+ );
228
+
229
+ });
230
+
231
+ }
232
+
233
+ }
234
+
235
+
236
+
237
+ ```
238
+
239
+
240
+
241
+ ###view画面のソースコード
242
+
243
+
244
+
245
+ ```dart
246
+
247
+ import 'package:assets_audio_player/assets_audio_player.dart';
248
+
249
+ import 'package:flutter/material.dart';
250
+
35
251
  import 'package:webview_flutter/webview_flutter.dart';
36
252
 
37
253
  import 'package:shared_preferences/shared_preferences.dart';
@@ -48,7 +264,7 @@
48
264
 
49
265
 
50
266
 
51
- viewScreen({Key key, @required this.url}) : super(key: key);
267
+ ViewScreen({Key key, @required this.url}) : super(key: key);
52
268
 
53
269
 
54
270
 
@@ -62,19 +278,19 @@
62
278
 
63
279
  class ViewScreenState extends State<ViewScreen> {
64
280
 
281
+ Future<String> _future;
282
+
65
283
  String _view = "message";
66
284
 
67
285
 
68
286
 
69
- void _load() async {
287
+ Future<String> _load() async {
70
288
 
71
289
  SharedPreferences pref = await SharedPreferences.getInstance();
72
290
 
73
- setState(() {
74
-
75
- _view = pref.getString('url') ?? '';
291
+ _view = pref.getString('url') ?? '';
76
-
292
+
77
- });
293
+ return Future.value(_view);
78
294
 
79
295
  }
80
296
 
@@ -86,7 +302,7 @@
86
302
 
87
303
  super.initState();
88
304
 
89
- _load();
305
+ _future = _load();
90
306
 
91
307
  }
92
308
 
@@ -98,33 +314,107 @@
98
314
 
99
315
  return Scaffold(
100
316
 
101
- appBar: AppBar(
102
-
103
- title: Text(_view),
104
-
105
- ),
106
-
107
- drawer: DrawerScreen(),
108
-
109
- body: WebView(
110
-
111
- initialUrl: _view,
112
-
113
- javascriptMode: JavascriptMode.unrestricted,
114
-
115
- javascriptChannels: Set.from([
116
-
117
- JavascriptChannel(
118
-
119
- name: "getData",
120
-
121
- onMessageReceived: (JavascriptMessage result) {
122
-
123
- }),
124
-
125
- ]),
126
-
127
- ),
317
+ drawer: DrawerScreen(),
318
+
319
+ body: FutureBuilder(
320
+
321
+ future: _future,
322
+
323
+ builder: (context, AsyncSnapshot<String> snapshot) {
324
+
325
+ switch (snapshot.connectionState) {
326
+
327
+ case ConnectionState.none:
328
+
329
+ return Text('none');
330
+
331
+ case ConnectionState.waiting:
332
+
333
+ return Center(child: CircularProgressIndicator());
334
+
335
+ case ConnectionState.active:
336
+
337
+ return Text('');
338
+
339
+ case ConnectionState.done:
340
+
341
+ if (snapshot.hasError) {
342
+
343
+ return Text(
344
+
345
+ '${snapshot.error}',
346
+
347
+ style: TextStyle(color: Colors.red),
348
+
349
+ );
350
+
351
+ } else {
352
+
353
+ return WebView(
354
+
355
+ initialUrl: _view,
356
+
357
+ javascriptMode: JavascriptMode.unrestricted,
358
+
359
+ javascriptChannels: Set.from([
360
+
361
+ JavascriptChannel(
362
+
363
+ name: "getData",
364
+
365
+ onMessageReceived: (JavascriptMessage result) {
366
+
367
+ if (result.message == "play sound") {
368
+
369
+ AssetsAudioPlayer().open(
370
+
371
+ Audio("assets/announce.wav"),
372
+
373
+ );
374
+
375
+ }
376
+
377
+ }),
378
+
379
+ ]),
380
+
381
+ );
382
+
383
+ }
384
+
385
+ }
386
+
387
+ }));
388
+
389
+ }
390
+
391
+ }
392
+
393
+
394
+
395
+ Future<void> main() async {
396
+
397
+ WidgetsFlutterBinding.ensureInitialized();
398
+
399
+ SharedPreferences pref = await SharedPreferences.getInstance();
400
+
401
+ await pref.setString('url', '');
402
+
403
+ runApp(MyApp());
404
+
405
+ }
406
+
407
+
408
+
409
+ class MyApp extends StatelessWidget {
410
+
411
+ @override
412
+
413
+ Widget build(BuildContext context) {
414
+
415
+ return MaterialApp(
416
+
417
+ home: ViewScreen(),
128
418
 
129
419
  );
130
420
 
@@ -138,96 +428,6 @@
138
428
 
139
429
 
140
430
 
141
- ### 試したこと
142
-
143
- ネットワークの設定が要るのかと思い`https://twitter.com/home`を直接`initialUrl`に(Webviewで表示させたいURLを`String`で設定する部分)書き込むと接続はできました。
144
-
145
-
146
-
147
- また、` SharedPreferences`を使わずに以下のように書くと、求める結果が得られました
148
-
149
-
150
-
151
- ```dart
152
-
153
- import 'package:assets_audio_player/assets_audio_player.dart';
154
-
155
- import 'package:flutter/material.dart';
156
-
157
- import 'package:webview_flutter/webview_flutter.dart';
158
-
159
- import 'Widgets/drawer.dart';
160
-
161
-
162
-
163
- class ViewScreen extends StatefulWidget {
164
-
165
- static const routeName = '/view';
166
-
167
- final String url;
168
-
169
-
170
-
171
- ViewScreen({Key key, @required this.url}) : super(key: key);
172
-
173
-
174
-
175
- @override
176
-
177
- State<StatefulWidget> createState() =>ViewScreenState();
178
-
179
- }
180
-
181
-
182
-
183
- classViewScreenState extends State<ViewScreen> {
184
-
185
- @override
186
-
187
- Widget build(BuildContext context) {
188
-
189
- return Scaffold(
190
-
191
- appBar: AppBar(
192
-
193
- title: Text(widget.url),
431
+ [1]~[2]の実装自体がよくないのでしょうか?
194
-
195
- ),
432
+
196
-
197
- drawer: _drawer(context),
198
-
199
- body: WebView(
200
-
201
- initialUrl: widget.url,
202
-
203
- javascriptMode: JavascriptMode.unrestricted,
204
-
205
- javascriptChannels: Set.from([
206
-
207
- JavascriptChannel(
208
-
209
- name: "getData",
210
-
211
- onMessageReceived: (JavascriptMessage result) {
212
-
213
- }),
214
-
215
- ]),
216
-
217
- ),
218
-
219
- );
220
-
221
- }
222
-
223
- }
224
-
225
-
226
-
227
- ```
228
-
229
- ![イメージ説明](8e27898e1181384b3faecd44efe09720.png)
230
-
231
-
232
-
233
- 心当りのある方は、ご指摘いたけると幸です。
433
+ どなご指摘