Flutterを学習していると、ナビゲーションに行きました。 Androidのアクティビティ間でデータを渡す および iOSのView Controller間でデータを渡す と同様に、画面間でデータを渡します。 Flutterでどうすればよいですか?
関連する質問:
この回答は、データの転送とデータの転送の両方をカバーします。 AndroidアクティビティおよびiOS ViewControllerとは異なり、Flutterの異なる画面は単なるウィジェットです。それらの間をナビゲートするには、ルートと呼ばれるものを作成し、Navigator
を使用してスタックのオンとオフにルートをプッシュおよびポップします。
次の画面にデータを送信するには、次のことを行います。
SecondScreen
コンストラクターに、送信するデータのタイプのパラメーターを取得させます。この特定の例では、データはString
値として定義され、ここでthis.text
で設定されます。
class SecondScreen extends StatelessWidget {
final String text;
SecondScreen({Key key, @required this.text}) : super(key: key);
...
次に、Navigator
ウィジェットのFirstScreen
を使用して、SecondScreen
ウィジェットにルートをプッシュします。送信するデータを、コンストラクターのパラメーターとして配置します。
Navigator.Push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(text: 'Hello',),
));
main.Dart
の完全なコードは次のとおりです。
import 'package:flutter/material.Dart';
void main() {
runApp(MaterialApp(
title: 'Flutter',
home: FirstScreen(),
));
}
class FirstScreen extends StatefulWidget {
@override
_FirstScreenState createState() {
return _FirstScreenState();
}
}
class _FirstScreenState extends State<FirstScreen> {
// this allows us to access the TextField text
TextEditingController textFieldController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('First screen')),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(32.0),
child: TextField(
controller: textFieldController,
style: TextStyle(
fontSize: 24,
color: Colors.black,
),
),
),
RaisedButton(
child: Text(
'Go to second screen',
style: TextStyle(fontSize: 24),
),
onPressed: () {
_sendDataToSecondScreen(context);
},
)
],
),
);
}
// get the text in the TextField and start the Second Screen
void _sendDataToSecondScreen(BuildContext context) {
String textToSend = textFieldController.text;
Navigator.Push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(text: textToSend,),
));
}
}
class SecondScreen extends StatelessWidget {
final String text;
// receive data from the FirstScreen as a parameter
SecondScreen({Key key, @required this.text}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second screen')),
body: Center(
child: Text(
text,
style: TextStyle(fontSize: 24),
),
),
);
}
}
データを戻す場合、次のことを行う必要があります。
FirstScreen
で、Navigator
を使用して、SecondScreen
メソッドでasync
をプッシュ(開始)し、終了時に返される結果を待ちます。
final result = await Navigator.Push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(),
));
SecondScreen
に、Navigator
をポップするときにパラメーターとして返すデータを含めます。
Navigator.pop(context, 'Hello');
その後、FirstScreen
でawait
が終了し、結果を使用できます。
setState(() {
text = result;
});
参照用のmain.Dart
の完全なコードを次に示します。
import 'package:flutter/material.Dart';
void main() {
runApp(MaterialApp(
title: 'Flutter',
home: FirstScreen(),
));
}
class FirstScreen extends StatefulWidget {
@override
_FirstScreenState createState() {
return _FirstScreenState();
}
}
class _FirstScreenState extends State<FirstScreen> {
String text = 'Text';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('First screen')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(32.0),
child: Text(
text,
style: TextStyle(fontSize: 24),
),
),
RaisedButton(
child: Text(
'Go to second screen',
style: TextStyle(fontSize: 24),
),
onPressed: () {
_awaitReturnValueFromSecondScreen(context);
},
)
],
),
),
);
}
void _awaitReturnValueFromSecondScreen(BuildContext context) async {
// start the SecondScreen and wait for it to finish with a result
final result = await Navigator.Push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(),
));
// after the SecondScreen result comes back update the Text widget with it
setState(() {
text = result;
});
}
}
class SecondScreen extends StatefulWidget {
@override
_SecondScreenState createState() {
return _SecondScreenState();
}
}
class _SecondScreenState extends State<SecondScreen> {
// this allows us to access the TextField text
TextEditingController textFieldController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second screen')),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(32.0),
child: TextField(
controller: textFieldController,
style: TextStyle(
fontSize: 24,
color: Colors.black,
),
),
),
RaisedButton(
child: Text(
'Send text back',
style: TextStyle(fontSize: 24),
),
onPressed: () {
_sendDataBack(context);
},
)
],
),
);
}
// get the text in the TextField and send it back to the FirstScreen
void _sendDataBack(BuildContext context) {
String textToSendBack = textFieldController.text;
Navigator.pop(context, textToSendBack);
}
}
最も簡単な方法
FirstPage.Dart
Navigator.Push(
context,
MaterialPageRoute(
builder: (context) => PasswordRoute(usernameController)));
// usernameControllerは文字列値です。複数の値を渡す場合は、すべて追加します
SecondPage.Dart
class PasswordRoute extends StatefulWidget {
final String usernameController;//if you have multiple values add here
PasswordRoute(this.usernameController, {Key key}): super(key: key);//add also..example this.abc,this...
@override
State<StatefulWidget> createState() => _PasswordPageState();
}
class _PasswordPageState extends State<PasswordRoute> {
@override
Widget build(BuildContext context) {
...child: Text(widget.usernameController);
}
}
一ページ目:
Navigator.of(context).Push(MaterialPageRoute(builder:(context)=>SecondPage('something')));
2ページ目:
class SecondPage extends StatefulWidget {
String something;
SecondPage(this.something);
@override
State<StatefulWidget> createState() {
return SecondPageState(this.something);
}
}
class SecondPageState extends State<SecondPage> {
String something;
SecondPageState(this.something);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
//now you have passing variable
title: Text(something),
),
...
}