【问题标题】:How to set the state of a stateful widget from a child stateless widget如何从子无状态小部件设置有状态小部件的状态
【发布时间】:2021-02-16 11:35:49
【问题描述】:

好的,所以提醒你一下,我今年 15 岁,完全是个飘飘然的菜鸟。这是我的第一个项目,所以请原谅这个可能很愚蠢的问题,请放轻松。 我有这个有状态小部件(ride),其中主体是_children 中定义的子无状态小部件之一。 if 语句仅在第一个和第二个子小部件之间更改,具体取决于用户是否连接了 BT 设备(该部分无关紧要)。 我需要做的是从 ln 68 上的MaterialButton 内部设置状态,以便ride 显示riding 无状态小部件,但显然我无法从startRide 内部更改状态,因为它是一个无状态的小部件。我该怎么做呢?

import 'package:audioplayers/audioplayers.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' ;
import 'results.dart';
import 'settings.dart';


class ride extends StatefulWidget {
  @override
  _rideState createState() => _rideState();
}

class _rideState extends State<ride> {
  int _currentState = 0;
  final List<Widget> _children = [
    notConnected(),
    startRide(),
    riding(),
  ];

  bool connected = checkBT(); // Function defined in settings.dart


  @override
  Widget build(BuildContext context) {
    if (connected == true){
      _currentState = 1;
      setState((){_currentState;});
    }
    return _children[_currentState];
  }
}

class notConnected extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(

      body: Container(
        height:180,
        padding: EdgeInsets.fromLTRB(40, 0, 40, 0),
        child: Center(
          child: Text(
            "Oops! Looks like your phone isn’t connected to your bluetooth device.",
            style:Theme.of(context).textTheme.bodyText2,
            textAlign: TextAlign.center,
          ),
        ),
      ),

    );
  }
}

class startRide extends StatelessWidget {
  AudioPlayer _audioPlayer = AudioPlayer();
  AudioCache player = AudioCache();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body:Center(
        child: Container(
          width: 200,
          height: 80,
          child: MaterialButton(
            onPressed:(){
              player.play("beeps.mp3");
              // I NEED TO SET THE STATE OF RIDE HERE
            },

            child: Text(
              "Start!",
              style: Theme.of(context).textTheme.headline1,
            ),
            color: Colors.red[500],
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.all(Radius.circular(40.0)),


          ),
      ),
      ),
      ),
    );

  }

}

class riding extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(); //not finished writing this yet
  }
}

我可能会以完全错误的方式来做这件事,但我来自 python,所以它非常不同。任何帮助将不胜感激:)

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    你可以创建回调,即传递函数

    这是一个示例代码

    import 'package:audioplayers/audioplayers.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart' ;
    import 'results.dart';
    import 'settings.dart';
    
    
    class ride extends StatefulWidget {
      @override
      _rideState createState() => _rideState();
    }
    
    class _rideState extends State<ride> {
      int _currentState = 0;
      final List<Widget> _children = [
        notConnected(),
        startRide((){
          // you can setState((){}) here
        }),
        riding(),
      ];
    
      bool connected = checkBT(); // Function defined in settings.dart
    
    
      @override
      Widget build(BuildContext context) {
        if (connected == true){
          _currentState = 1;
          setState((){_currentState;});
        }
        return _children[_currentState];
      }
    }
    
    class notConnected extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
    
          body: Container(
            height:180,
            padding: EdgeInsets.fromLTRB(40, 0, 40, 0),
            child: Center(
              child: Text(
                "Oops! Looks like your phone isn’t connected to your bluetooth device.",
                style:Theme.of(context).textTheme.bodyText2,
                textAlign: TextAlign.center,
              ),
            ),
          ),
    
        );
      }
    }
    
    class startRide extends StatelessWidget {
      AudioPlayer _audioPlayer = AudioPlayer();
      AudioCache player = AudioCache();
      Function callback;
    
      startRide(Function callback){
         this.callback = callback;
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body:Center(
            child: Container(
              width: 200,
              height: 80,
              child: MaterialButton(
                onPressed:(){
                  player.play("beeps.mp3");
                  // I NEED TO SET THE STATE OF RIDE HERE
                  // callback function
                  callback();
                },
    
                child: Text(
                  "Start!",
                  style: Theme.of(context).textTheme.headline1,
                ),
                color: Colors.red[500],
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.all(Radius.circular(40.0)),
    
    
              ),
          ),
          ),
          ),
        );
    
      }
    
    }
    
    class riding extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(); //not finished writing this yet
      }
    }
    

    编辑:- 测试代码

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Test(),
        );
      }
    }
    
    class Test extends StatefulWidget {
      @override
      _Test createState() => _Test();
    }
    
    class _Test extends State<Test> {
    
      int current = 0;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: root(),
        );
      }
    
      Widget root() {
        return Container(
          child: TestingStateless((){
            setState(() {
              current++;
              print(current);
            });
          }),
        );
      }
    }
    
    // ignore: must_be_immutable
    class TestingStateless extends StatelessWidget{
      Function func;
    
      TestingStateless(Function func){
        this.func = func;
      }
    
      @override
      Widget build(BuildContext context) {
        return InkWell(
          onTap: (){
            func();
          },
          child: Container(
            height: 50,
            color: Colors.green,
            child: Text('TESTING'),
          ),
        );
      }
    }
    

    【讨论】:

    • 如何从startRide 中的MaterialButton 触发?
    • 在你的 startRide 类中搜索函数回调
    • 好的,我实现了你所说的。我不知道我是否做错了,但是我在哪里放了setState,我收到一条错误消息The instance member 'setState' can't be accessed in an initializer. 这是我为该部分编写的代码:``` final List _children = [ notConnected( ), startRide((){ setState;{ _currentState = 2; } }), 骑行(), ];``
    • @ArduinoBobby 我创建了一个测试代码并且工作正常。如果您可以更新整个代码,它可能会帮助人们发现错误。我已经为您编辑并粘贴了我的测试代码(示例)。你可以看看。
    猜你喜欢
    • 2021-06-11
    • 2019-10-06
    • 2018-09-01
    • 2020-10-19
    • 2021-09-21
    • 2021-12-15
    • 2019-06-26
    • 2020-01-05
    • 2021-05-19
    相关资源
    最近更新 更多