ステートレスウィジェットでTextFormFieldをScopedModelと共に使用して、その中のテキストを処理しようとしています。次のようなさまざまな問題に直面しています。
フィールドにコントローラを使用してみましたが、テキストを入力してキーボードの[done]を押すたびに、テキストがクリアされます。理由はわかりません。
コントローラを削除すると、テキストがフィールドに残りますが、フィールドからテキストを取得する方法に関して新しい問題が発生します。コールバックonFieldSubmittedを使用して解決しました。
しかし、結局のところ、onFieldSubmittedは、キーボードの完了ボタンをクリックしたときにのみ呼び出されます。フィールドにテキストを入力して[OK]をクリックする代わりに別のフィールドをクリックすると、コールバックが呼び出されず、ユーザーがフィールドに入力した内容を追跡する方法がありません。
これに対する解決策はありますか?
問題のサンプルコードを添付しています。
class LoginPageStateless extends StatelessWidget {
final loginUsernameController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: true,
body: ScopedModelDescendant<AccountModel>(
builder: (context, child, model) {
return Form(
//key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextFormField(
style: TextStyle(fontSize: 15.0),
decoration: InputDecoration(
labelText: 'Email id',
hintText: '[email protected]',
),
controller: loginUsernameController,
onFieldSubmitted: model.updateLoginUsernameText,
),
TextFormField(
style: TextStyle(fontSize: 15.0),
decoration: InputDecoration(
labelText: 'Password',
),
controller: loginUsernameController,
onFieldSubmitted: model.updateLoginUsernameText,
obscureText: true,
),
],
),
);
},
),
);
}
}
長期変数を格納するためにStateless
ウィジェットを使用することはできません。
問題は、それがまさにあなたがしようとしていることです。 TextEditingController
は、レンダリング間で保持する必要があるクラスインスタンスです。しかし、それをStatelessWidget
に保存することで、基本的には更新のたびに再作成します。
代わりに、ウィジェットをStateful
に変換する必要があります。そして、そのコントローラーをState
パーツに移動します
私はこれまでTextFormFieldを使用していませんでしたが、シンプルさと柔軟性のため、常にTextField()を使用しています。トップレベルストアに単一の真実のソースがあるため、Reduxウィジェットとステートレスウィジェットを使用するときに同様の問題が発生しました。そのため、ViewModel内にいくつかのコールバックを作成し、そのコールバックを文字列パラメーターを受け取るテキストフィールドコールバック 'onChanged'に割り当てる必要がありました。
CustomTextWidgetWrapper(
onChangedCallback: viewModel.onChanged
),
ウィジェットにラップされたTextFieldで(詳細は示さない)
new TextField(
controller: myController, // no use practically now
onChanged: onChangedCallback,
そして、ビューモデルでは、文字列を取得し、データを取得してサーバーに送信するボタンのように、他のウィジェットで再利用するために中央ストレージにディスパッチします
static ViewModel fromStore(Store<AppState> store) {
return new ViewModel(
onChanged: (String textFieldText) {
// I call dispatch or an API here if I want
store.dispatch(new CallAPI(params: textFieldText);