从无状态小部件调用有状态小部件的 setState

Posted

技术标签:

【中文标题】从无状态小部件调用有状态小部件的 setState【英文标题】:Call a setState of a statefull widget from the stateless widget 【发布时间】:2020-10-19 14:57:32 【问题描述】:

我有一个无状态小部件类,它有一个需要跟踪其运动的小部件。我不能将此小部件保留在有状态小部件中,因为我不希望刷新此小部件的状态。

我有以下代码。

import 'package:flutter/material.dart';
import 'package:control_pad/control_pad.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return new MaterialApp(
    home: new MyHomePage(),
   );
  


class MyHomePage extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Container(
      color: Colors.white,
      child: Column(
        children: <Widget>[
          Expanded(
            child: JoystickView(
              onDirectionChanged: (degree, direction) 
                //Change the state here.
              ,
            ),
          ),
          Expanded(
            child: MyStateFull(),
          ),
        ],
      ),
    );
  


class MyStateFull extends StatefulWidget 
  @override
  _MyStateFullState createState() => _MyStateFullState();


class _MyStateFullState extends State<MyStateFull> 
  double degree = 10;
  double direction = 10;

  //Call this from the stateless Widget
  void changedDirection(degree, direction) 
    setState(() 
      this.degree = degree;
      this.direction = direction;
    );
  

  @override
  Widget build(BuildContext context) 
    return Container(
      child: Text(
        "The degree Moved is $degree and the direction is $direction",
        style: TextStyle(fontSize: 25, color: Colors.black),
      ),
    );
  

此代码产生以下输出。

我希望随着操纵杆的移动而改变方向和角度值。

谢谢。

【问题讨论】:

【参考方案1】:

我自己尝试过并找到了解决方案。这可以使用流来完成。我会发布代码以防有人将来需要它。

import 'package:flutter/material.dart';
import 'package:control_pad/control_pad.dart';

class MyStateLess extends StatelessWidget 
  StreamController<List<double>> _controller = StreamController<List<double>>();

  GlobalKey<_MyStateFullState> statefulKey = new GlobalKey<_MyStateFullState>();

  @override
  Widget build(BuildContext context) 
    return Column(
      children: <Widget>[
        JoystickView(
          onDirectionChanged: (degree, direction) 
            List<double> temp = new List<double>();
            temp.add(degree);
            temp.add(direction);
            _controller.add(temp);
          ,
        ),
        MyStateFull(stream: _controller.stream, key: statefulKey),
      ],
    );
  


class MyStateFull extends StatefulWidget 
  final Stream<List<double>> stream;
  MyStateFull(Key key, @required this.stream) : super(key: key);

  @override
  _MyStateFullState createState() => _MyStateFullState();


class _MyStateFullState extends State<MyStateFull> 
  double _degree = 0.0;
  double _direction = 0.0;

  @override
  void initState() 
    super.initState();
    widget.stream.listen((event) 
      setState(() 
        _degree = event[0];
        _direction = event[1];
      );
    );
  

  @override
  Widget build(BuildContext context) 
    return Container(
      child: Text("$_degree, $_direction"),
    );
  

【讨论】:

以上是关于从无状态小部件调用有状态小部件的 setState的主要内容,如果未能解决你的问题,请参考以下文章

我的有状态小部件不会更新 ui,即使我正在调用 setState 并将正确的值传递给小部件类

在颤振中从父小部件调用 setState 不会更新状态

Flutter:在构造函数中调用 setState():_SharesListState#6c96a(生命周期状态:已创建,无小部件,未安装)

Flutter - setState 不更新内部有状态小部件

Flutter:从子 StreamBuilder 更新有状态小部件

编辑文本控制器更新小部件值而不调用 setState() - Flutter