この質問に続いて、StatefulWidgetsがReduxベースのフラッターアプリのコンテキストで意味をなす理由を理解しました。そしてそれは私も達成しようとしていることです-
アプリ全体の状態(ログインしたユーザーの詳細、APIデータなど)から情報が「供給」され、接続されたViewModelからアクションをディスパッチできるページですが、スコープが小さく、存続期間が短いステートフルウィジェットも含まれています。状態。アニメーション、送信前にその場でユーザー入力を検証する、ユーザーアクションに基づいてUIを変更するなど。
だから私はどのように興味があり、ここの誰かが私を助けてくれることを願っています。現在、私の「ページ」はすべて、次の方法でストアを介してアプリの状態に接続されているステートレスウィジェットです。
class LoginPage extends StatelessWidget {
final String TAG = "LoginPage";
bool isGreen = false;
LoginPage({Key key}) : super(key: key);
void changeColor() {
isGreen = !!isGreen;
}
@override
Widget build(BuildContext context) {
/// [StoreConnector] is used to convert store data (using the fromStore)
/// into a ViewModel suitable for the page.
return StoreConnector<AppState, LoginPageViewModel>(
builder: (context, viewModel) {
return Scaffold(
body: Column(
children: <Widget>[
Container(...),
Text(
text: viewModel.some_value_from_the_store,
color: isGreen ? Colors.green : Colors.red,
),
ElevatedButton(
onPressed: () => changeColor(),
child: Text('Press to change color'),
)
],
));
},
converter: LoginPageViewModel.fromStore);
}
}
ここでは、ユーザーのクリックに基づいて「LoginPage」ウィジェット内のテキストの色を変更しようとしていますが、ストアに接続したままにして、UIが到着したときに新しいアプリの状態情報で更新し続けるようにしています。
このようなものについての参照はありますか?誰かが例、またはこれを達成する方法の基本的なガイドラインを提供できますか?簡単そうに見えますが、私はそれに苦労しています。
ここに役立つかもしれないいくつかのアイデアがあります。
ウィジェットはステートフルである必要があります。あなたは時間とともに変化する色を追跡しようとしています。ステートレスウィジェットは最終プロパティのみを許可します。つまり、作成時にのみ値を開始できます。
変数isGreenとメソッドchangeColor()は、状態オブジェクトの一部である必要があります。build()メソッドもそこに移動します。
次へ-メソッドを呼び出すときは、次を呼び出す必要があります。
void changeColor() {
setState(() {isGreen = !isGreen;});
}
あなたのコードでは、値を反転していないと思います(= !! iGreenは= isGreenと同じです)。しかし、もっと重要なのは、ウィジェットを再構築する必要があることをフレームワークに伝えていないことです。これを自分でテストできます。1回クリックします(「!!」を修正した後)。何も起こりません。エミュレータで強制的に更新すると、色が変わったことがわかります。これは、手動で更新したためです。setState()はあなたに代わってそれを行います:それはあなたが提供したコードを実行し、次にFlutterを呼び出してウィジェットを更新するように指示します。参照-flutterには魔法のトリガーがなく、ウィジェットを更新するタイミングを決定するためのコードを監視しません。setState()は、そうするように指示します。
原則として、アプリケーションの状態-つまり、複数のウィジェット(またはページ)と共有されるデータは、ウィジェットツリーを「持ち上げ」、プロバイダークラスに保持する必要があります。
ステートフルウィジェットは、ウィジェットに直接関連するデータのみを保持する必要があります。通常、これはプロバイダーデータのレンダリングに役立つデータです。次に例を示します。-Providerは、表示するアイテムのリストを保持します。ステートフルウィジェットは、現在選択されているアイテムを追跡します-プロバイダーは、表示されるテキストを保持します。Statefulウィジェットはフォントサイズ、フォントの色などを保持し、ユーザーがその特定のウィジェットでそれを変更できるようにしますが、同じデータを使用するすべてのウィジェットで変更できるわけではありません。
あなたの例では、クラウドの画面に複数のログインウィジェットがあります(何らかの理由で)。その場合:-すべてのログインウィジェットの色を変更する場合-プロバイダークラスでisGreenを保持します。その場合、ウィジェットはステートレスにすることができます。-クリックしたウィジェットだけで色を変更したい場合-他の誰もこの値を気にしないので、これはステートフルウィジェットに属します。
あなたが望むことをするはずのコードでこれを更新させてください。ウィジェットをストアに接続することは、ステートフルウィジェットとステテレスウィジェットで同じように機能します。
注-ウィジェットがどのように色を変更するかを示すために、ストアに接続するコードをコメントアウトしました。ストアコードのコメントを外すと、準備が整います。
これはhttps://dartpad.dev/ですばやく実行でき、コードをコピーして貼り付けるだけです。
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: LoginPage(),
);
}
}
class LoginPage extends StatefulWidget {
final String TAG = "LoginPage";
LoginPage({Key key}) : super(key: key);
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
bool isGreen = false;
void changeColor() {
setState(() {
isGreen = !isGreen;
});
}
@override
Widget build(BuildContext context) {
/// [StoreConnector] is used to convert store data (using the fromStore)
/// into a ViewModel suitable for the page.
//return StoreConnector<AppState, LoginPageViewModel>(
//builder: (context, viewModel) {
return Scaffold(
body: Column(
children: <Widget>[
Container(),
Text(
'viewModel.some_value_from_the_store',
style: TextStyle(color: isGreen ? Colors.green : Colors.red),
),
ElevatedButton(
onPressed: () => changeColor(),
child: Text('Press to change color'),
)
],
));
//},
//converter: LoginPageViewModel.fromStore);
//}
}
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加