フォームが必要なFlutterアプリを開発しています。したがって、ユーザーがアプリを開くと、次のコードを持つフォームの前にスプラッシュスクリーンが表示されます。
import 'package:flutter/material.Dart';
import '../model/User.Dart';
import './FileManager.Dart';
import './MyListPage.Dart';
class UserLoader extends StatefulWidget {
@override
_UserLoaderState createState() => new _UserLoaderState();
}
class _UserLoaderState extends State<UserLoader> {
final userFileName = "user_infos.txt";
User _user;
@override
Widget build(BuildContext context) {
print("build UserLoader");
final _formKey = new GlobalKey<FormState>();
final _firstNameController = new TextEditingController();
final _lastNameController = new TextEditingController();
final _emailController = new TextEditingController();
final _phoneController = new TextEditingController();
return new Scaffold(
appBar: new AppBar(
title: new Text("Informations"),
actions: <Widget>[
new IconButton(
icon: const Icon(Icons.save),
onPressed: () {
_user = _onFormValidate(
_formKey.currentState,
_firstNameController.text,
_lastNameController.text,
_emailController.text,
_phoneController.text);
})
],
),
body: new Center(
child: new SingleChildScrollView(
child: new Form(
key: _formKey,
child: new Column(children: <Widget>[
new ListTile(
leading: const Icon(Icons.person),
title: new TextFormField(
decoration: new InputDecoration(
hintText: "Prénom",
),
keyboardType: TextInputType.text,
controller: _firstNameController,
validator: _validateName,
),
),
new ListTile(
leading: const Icon(Icons.person),
title: new TextFormField(
decoration: new InputDecoration(
hintText: "Nom",
),
keyboardType: TextInputType.text,
controller: _lastNameController,
validator: _validateName,
),
),
Etc, etc ...
ただし、TextFieldをタップすると、キーボードが表示されてすぐに閉じ、すべてのコンポーネントが再構築されます。そのため、フォームに記入することはできません。
誰かが解決策を手に入れられますか?前もって感謝します !
このためのコード全体を提供していないため、コンテキストが何であるかわかりません。
私自身が陥った1つの落とし穴(そして、私があなたの説明から収集したように、あなたに影響を与えているかもしれません)は、ステートフルウィジェットが別のステートフルウィジェット内にネストされていることです。
例えば、
_class Parent extends StatefulWidget {
@override
ParentState createState() => ParentState();
(...)
}
class ParentState extends State<Parent> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Child(),
);
}
(...)
}
class Child extends StatefulWidget {
@override
ChildState createState() => ChildState();
(...)
}
class ChildState extends State<Child> {
@override
Widget build(BuildContext context) {
return TextField(...);
}
(...)
}
_
ここでの問題は、親の再構築がParentState().build()
が実行され、新しいChild
でnewChildState
インスタンスが作成されることを意味しますオブジェクト。すべてをリセットします。
ChildWidgetを再作成せずに、ParentStateに保存してみてください。
_class Parent extends StatefulWidget {
@override
ParentState createState() => ParentState();
(...)
}
class ParentState extends State<Parent> {
Child _child;
@override
void initState() {
_child = Child();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: child,
);
}
(...)
}
// The rest remains the same
_
編集:ウィジェットツリーがもう少し複雑な場合は、1)親からのコールバックを渡して状態の変化を通知する必要があること、2)setState()を呼び出すことも忘れないでください。子。
新しいクラスを作成し、問題が発生したターゲットクラスにインポートするだけです。例えば :
私は通常、次のようなクラスを作成します。
class MiddleWare
{
static MiddleWare shared = MiddleWare();
_MiddleWare(){}
String myText = "my Text";
// every variables should be here...
}
そして
import "MiddleWare.Dart";
class myclass extends StatefulWidget {
@override
_myclassState createState() => _myclassState();
}
class _myclassState extends State<myclass> {
@override
Widget build(BuildContext context) {
return Container(child: Text(MiddleWare.shared.myText));
}
}
それでおしまい。
このようなコンテキストを受け取る関数を作成してみてください
class YourPage extends StatefulWidget {
const YourPage(Key key) : super(key: key);
static Future<void> show({ BuildContext context,}) async {
await Navigator.of(context, rootNavigator: true).Push(
MaterialPageRoute(
builder: (context) => YourPage()
);}
@override
_YourPageState createState() => _YourPageState();
}
......YourPage Build.....
次に、ページにコンテキストを提供します。再構築すると、親の再構築を妨げるコアコンテキストが含まれます。
onPressed: () async {
await YourPage.show(context: context);