我在 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 次  |  
        
|   最近记录:  |