在 StatefulBuilder 小部件之外设置 StatefulBuilder 状态

Rap*_*uer 3 dart flutter flutter-layout

StatefulBuilder我正在尝试在其小部件之外设置小部件状态。大多数示例和可用文档显示了setState小部件内部使用的方法,但是我想知道是否可以从小部件外部调用此类方法StatefulBuilder。这是一个例子:

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;
    });
  }


}
Run Code Online (Sandbox Code Playgroud)

_iconColor目前,由于在 中使用了变量,我收到错误setState。我还知道可能无法在小部件之外访问它。如果是这种情况,那么在不重建整个图标的情况下更改图标颜色的更好解决方案是什么StatefulWidget

谢谢你的时间。

Dar*_*han 8

您可以使用该ValueListenableBuilder小部件。
例子:

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
}
Run Code Online (Sandbox Code Playgroud)