简体   繁体   English

在 StatefulBuilder 小部件之外设置 StatefulBuilder state

[英]Set StatefulBuilder state outside of StatefulBuilder widget

I'm trying to set a StatefulBuilder widget state outside of its widget.我正在尝试在其小部件之外设置一个StatefulBuilder小部件 state 。 Most examples and the documentation available show the setState method being used inside the widget, however I'm wondering if such method can be called from outside of the StatefulBuilder widget.大多数示例和可用的文档都显示了在小部件内部使用的setState方法,但是我想知道是否可以从StatefulBuilder小部件外部调用这种方法。 Here's an example:这是一个例子:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'StackOverflow Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'StackOverflow Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      //Change one of the icon's color using the tap down function
      onTapDown: (TapDownDetails details) {
        return changeColor(details);
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text('Example'),
        ),
        body: Center(
          child: Column(children: [
            //This widget should be rebuilt
            StatefulBuilder(
                builder: (BuildContext context, StateSetter setState)
                {
                  Color _iconColor = Colors.black;
                  return Icon(
                    Icons.money,
                    size: 50,
                    color: _iconColor,
                  );
                }
            ),
            //This icon should not be rebuilt
            Icon(
              Icons.euro,
              size: 50,
              color: Colors.black,
            ),
          ]),
        ),
      ),
    );
  }

  void changeColor(TapDownDetails details) {
    //Rebuilt StatefulBuilder widget here, but how?
    setState(() {
      _iconColor = Colors.green;
    });
  }


}

Currently I get an error because of the _iconColor variable being used in setState .目前我收到一个错误,因为setState中使用了_iconColor变量。 I am also aware that it may be impossible to access it outside of the widget.我也知道在小部件之外可能无法访问它。 If that's the case, what would be a better solution to change the icon's color without resorting to rebuilding the whole StatefulWidget ?如果是这种情况,那么在不重建整个StatefulWidget的情况下更改图标颜色的更好解决方案是什么?

Thanks for your time.谢谢你的时间。

You can use the ValueListenableBuilder widget.您可以使用ValueListenableBuilder小部件。
Example:例子:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'StackOverflow Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'StackOverflow Example'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ValueNotifier _iconColor = ValueNotifier<Color>(Colors.black);
  
  @override
  Widget build(BuildContext context) {
    return new GestureDetector(
      //Change one of the icon's color using the tap down function
      onTapDown: (TapDownDetails details) {
        return changeColor(details);
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text('Example'),
        ),
        body: Center(
          child: Column(children: [
            //This widget should be rebuilt
            ValueListenableBuilder(
            valueListenable: _iconColor,
              builder: (ctx, value, child) {
               return Icon(
                    Icons.money,
                    size: 50,
                    color: value,
                  );
              }
            ),
            //This icon should not be rebuilt
            Icon(
              Icons.euro,
              size: 50,
              color: Colors.black,
            ),
          ]),
        ),
      ),
    );
  }

  void changeColor(TapDownDetails details) =>
    _iconColor.value = Colors.green
}

This is one way to achieve what you intend, if you have to definitely use the StatefulBuilder .如果您必须绝对使用StatefulBuilder ,这是实现您想要的一种方法。

Basically we are storing the StateSetter that we receive from the StatefulBuilder.builder基本上我们正在存储从StatefulBuilder.builder收到的StateSetter

class Sample extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return SampleState();
  }
}

class SampleState extends State<Sample> {
  StateSetter internalSetter;
  Color color = Colors.black;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: false,
      appBar: AppBar(title: Text('Sample')),
      body: Column(
        children: [
          GestureDetector(
            onTap: () {
              setState(() {
                color = Colors.deepOrange;
              });
            },
            child: Text('Press'),
          ),
          StatefulBuilder(builder: (context, setter) {
            internalSetter = setter;
            return Container(
              height: 100,
              width: 100,
              color: color,
            );
          }),
          Undisturbed(),
        ],
      ),
    );
  }
}

class Undisturbed extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print("Undisturbed is built");
    return Container(
      width: 100,
      height: 100,
      color: Colors.red,
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从外部更新 StatefulBuilder - update StatefulBuilder from outside 列表小部件 state 未使用 flutter 中的 StatefulBuilder 进行更新 - List widgets state is not updating with StatefulBuilder in flutter setState 在 StatefulBuilder 内部更新,但在使用外部方法时不更新 - setState updating inside StatefulBuilder but not updating when using a method outside Flutter:在 StatefulBuilder 的 AlertDialog 上使用 OK 按钮设置全局变量 - Flutter: Set global variable using OK button on AlertDialog in StatefulBuilder StatefulBuilder与StatefulWidget - StatefulBuilder vs StatefulWidget 有没有办法为 Flutter StatefulBuilder 设置一个定期计时器,以每 1 秒用 setState() 更新一次? - Is there a way to set a periodic timer for a Flutter StatefulBuilder to update with setState() every 1 second? Flutter 中的 StatefulBuilder VS StatefulWidget - 性能 - StatefulBuilder VS StatefulWidget in Flutter - performance Flutter - modalBottomSheet 中 StatefulBuilder 中的 TextField 不起作用 - Flutter - TextField in StatefulBuilder in modalBottomSheet not working StatefulBuilder 的 setState function 不改变 IconButton 的颜色 - StatefulBuilder's setState function not changing the color of IconButton 在 StatelessWidget 中使用 StatefulBuilder 时使用 dispose() - Using dispose() when using StatefulBuilder in a StatelessWidget
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM