我在 state 类中有一个方法,但我需要使用它的小部件类引用在外部访问该方法,
class TestFormState extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _testState();
}
}
class _testFormState extends State<TestFormState> {
int count = 1;
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Colors.green,
child: Text("Count : $count"),
),
);
}
clickIncrease(){
setState(() { count += 1; });
}
}
Run Code Online (Sandbox Code Playgroud)
我需要在另一个小部件中访问上述小部件的 clickIncrease,如下面的代码,
class TutorialHome extends StatelessWidget {
TestFormState test;
@override
Widget build(BuildContext context) {
// Scaffold is a layout for the major Material Components.
return Scaffold(
body: Column(
children: <Widget>[
test = TestFormState(),
FlatButton(
child: Text("Increase"),
onPressed: (){
test.state.clickIncrease(); // This kind of thing I need to do
},
),
]
),
);
}
Run Code Online (Sandbox Code Playgroud)
我写了上面的代码只是为了演示这个问题。
我有一个技巧,但我不知道这是否是一个不好的做法。
class TestFormState extends StatefulWidget {
_TestFormState _testFormState;
@override
State<StatefulWidget> createState() {
_testFormState = _TestFormState();
return _testFormState;
}
}
class _TestFormState extends State<TestFormState> {
int count = 1;
@override
Widget build(BuildContext context) {
return Center(
child: Container(
color: Colors.green,
child: Text("Count : $count"),
),
);
}
clickIncrease(){
setState(() { count += 1; });
}
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以在这里访问它:
class TutorialHome extends StatelessWidget {
TestFormState test;
@override
Widget build(BuildContext context) {
// Scaffold is a layout for the major Material Components.
return Scaffold(
body: Column(
children: <Widget>[
TextButton(
child: Text("Increase"),
onPressed: () {
test._testFormState
.clickIncrease(); // This is accessable
},
),
]
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
我建议看一下ValueNotifier
我认为有一种更好的方法来以简单的方式管理您的应用程序状态,并且我同意使用提供程序可能是有效的。
向应用程序内的所有小部件提供模型。我们使用它是
ChangeNotifierProvider因为这是在模型更改时重建小部件的简单方法。我们也可以只使用 Provider,但这样我们就必须自己听 Counter 了。阅读提供商的文档以了解所有可用的提供商。
在构建器中初始化模型。这样,Provider 就可以拥有 Counter 的生命周期,确保
dispose在不再需要时调用。
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Counter(),
child: MyApp(),
),
);
}
Run Code Online (Sandbox Code Playgroud)
最简单的模型,只有一个字段。
ChangeNotifier是 中的一个类flutter:foundation。Counter不依赖于提供者。
class Counter with ChangeNotifier {
int count = 1;
void clickIncrease() {
count += 1;
notifyListeners();
}
}
Run Code Online (Sandbox Code Playgroud)
Consumer查找祖先 Provider 小部件并检索其模型(在本例中为 Counter)。然后它使用该模型来构建小部件,并且如果模型更新,将触发重建。您可以在任何可以访问上下文的地方访问您的提供者。一种方法是使用
Provider<Counter>.of(context).提供程序包还定义了上下文本身的扩展方法。您可以调用
context.watch<Counter>()任何 widget 的构建方法来访问 Counter 的当前状态,并要求 Flutter 在 Counter 发生变化时重建您的 widget。您不能使用
context.watch()外部构建方法,因为这通常会导致微妙的错误。相反,您应该使用context.read<Counter>(),它会获取当前状态,但不会要求 Flutter 进行未来的重建。由于我们处于一个回调中,每当用户点击 时就会调用该回调
FloatingActionButton,因此我们不在此处的构建方法中。我们应该使用context.read().
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Scaffold is a layout for the major Material Components.
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Count:'),
Consumer<Counter>(
builder: (context, counter, child) => Text(
'${counter.value}',
style: Theme.of(context).textTheme.headline4,
),
),
],
),
),
// I've change the button to `FloatingActionButton` for better ui experience.
floatingActionButton: FloatingActionButton(
// Here is the implementation that you are looking for.
onPressed: () {
var counter = context.read<Counter>();
counter.increment();
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
完整代码:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => Counter(),
child: MyApp(),
),
);
}
class Counter with ChangeNotifier {
int count = 1;
void clickIncrease() {
count += 1;
notifyListeners();
}
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Count:'),
Consumer<Counter>(
builder: (context, counter, child) => Text(
'${counter.count}',
style: Theme.of(context).textTheme.headline4,
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
var counter = context.read<Counter>();
counter.clickIncrease();
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
实际应用程序:
有关提供程序包(Provider 的来源)的更多信息,请参阅包文档。
有关 Flutter 中状态管理的更多信息以及其他方法的列表,请访问flutter.dev 的状态管理页面。
| 归档时间: |
|
| 查看次数: |
3868 次 |
| 最近记录: |