使用其有状态小部件访问状态类的方法?

Sac*_*ara 8 dart flutter

我在 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)

我写了上面的代码只是为了演示这个问题。

Ism*_*rif 7

我有一个技巧,但我不知道这是否是一个不好的做法。

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


Mαπ*_*π.0 3

我认为有一种更好的方法来以简单的方式管理您的应用程序状态,并且我同意使用提供程序可能是有效的。

向应用程序内的所有小部件提供模型。我们使用它是 ChangeNotifierProvider因为这是在模型更改时重建小部件的简单方法。我们也可以只使用 Provider,但这样我们就必须自己听 Counter 了。

阅读提供商的文档以了解所有可用的提供商。

在构建器中初始化模型。这样,Provider 就可以拥有 Counter 的生命周期,确保dispose在不再需要时调用。

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => Counter(),
      child: MyApp(),
    ),
  );
}
Run Code Online (Sandbox Code Playgroud)

最简单的模型,只有一个字段。ChangeNotifier是 中的一个类flutter:foundationCounter不依赖于提供者。

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 的状态管理页面