[解決済み] Flutter initState メソッドでコンテキストを取得する
質問
私は
initState
がこのための正しい関数であるかどうかはわかりません。
私が実現しようとしているのは、ページがレンダリングされたときにいくつかのチェックを実行し、それらに基づいて
AlertDialog
を開き、必要であれば設定を行うことです。
あるページがあり、そのページには状態があります。
それは
initState
関数は次のようになります。
@override
void initState() {
super.initState();
if (!_checkConfiguration()) {
_showConfiguration(context);
}
}
は
_showConfiguration
をこのように
void _showConfiguration(BuildContext context) {
AlertDialog dialog = new AlertDialog(
content: new Column(
children: <Widget>[
new Text('@todo')
],
),
actions: <Widget>[
new FlatButton(onPressed: (){
Navigator.pop(context);
}, child: new Text('OK')),
],
);
showDialog(context: context, child: dialog);
}
このチェックを行い、必要に応じてモーダルを呼び出すためのより良い方法があれば、適切な方向性を示してください。
onState
または
onRender
関数に割り当てることができるコールバック、または
build
関数に割り当てることができますが、見つけることができませんでした。
編集: こちらでも同じような問題があったようです。 Flutter initStateでページへのリダイレクトを行う
どのように解決するのですか?
メンバ変数のコンテキストにアクセスできるのは
initState
でアクセスできますが、すべてに使えるわけではありません。これは
initState
のドキュメントからです。
を使うことはできません。
[BuildContext.inheritFromWidgetOfExactType]
を使うことはできません。 メソッドを使用することはできません。しかし[didChangeDependencies]
はこのメソッドの直後に呼び出されます。 はこのメソッドの直後に呼び出され[BuildContext.inheritFromWidgetOfExactType]
はそこで使うことができます。
初期化ロジックを
didChangeDependencies
に移動させることもできますが、それは必ずしもあなたの望むところではないかもしれません。
didChangeDependencies
はウィジェットのライフサイクルの中で何度も呼び出される可能性があるからです。
代わりに、ウィジェットが初期化された後まで呼び出しを委ねる非同期呼び出しを行う場合、意図したとおりにコンテキストを使用することができます。
これを行う簡単な方法は、futureを使用することです。
Future.delayed(Duration.zero,() {
... showDialog(context, ....)
}
もう一つの方法は、より「正しい」かもしれませんが、flutterのスケジューラを使ってフレーム後のコールバックを追加することです。
SchedulerBinding.instance.addPostFrameCallback((_) {
... showDialog(context, ....)
});
そして最後に、initState関数で非同期呼び出しを使うために、私が好きな小技を紹介します。
() async {
await Future.delayed(Duration.zero);
... showDialog(context, ...)
}();
以下は、単純なFuture.delayedを使った完全な例です。
import 'dart:async';
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
bool _checkConfiguration() => true;
void initState() {
super.initState();
if (_checkConfiguration()) {
Future.delayed(Duration.zero,() {
showDialog(context: context, builder: (context) => AlertDialog(
content: Column(
children: <Widget>[
Text('@todo')
],
),
actions: <Widget>[
FlatButton(onPressed: (){
Navigator.pop(context);
}, child: Text('OK')),
],
));
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
);
}
}
コメントで提供された OP からのより多くのコンテキストにより、彼らの特定の問題に対する少し良い解決策を提供することができます。アプリによっては、アプリを初めて開いたかどうかに応じて、表示するページを決定する必要があります(例: set
home
を異なるものに設定します。また、ダイアログはモバイルでは必ずしも最適な UI 要素ではありません。追加する必要のある設定と次のボタンを含む完全なページを表示する方がよい場合があります。
関連
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン