【问题标题】:Slider(created in custom class) not moving or updating滑块(在自定义类中创建)不移动或更新
【发布时间】:2019-03-16 10:45:25
【问题描述】:

我刚刚开始使用 Flutter 开发 Android 应用程序,并且我正在学习。

有关当前项目的详细信息: 我正在创建一个骰子模拟器,用户可以在其中点击绘制的骰子来掷骰子。我添加了振动效果,吐司也。现在我想让用户使用滑块修改骰子的大小。

我在文档中找到了slider class。 我还咨询了stackoverflow中的this线程。不过,我无法完全掌握这个概念。我将不胜感激。

问题:

所说的滑块确实呈现了它应该是的样子,但我似乎无法拖动它。

main.dart

import 'package:flutter/material.dart';
import 'package:do_dice/dice2D.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';

void showToastText(int a) {
  Fluttertoast
      .cancel(); //to clear all scheduled toast call ; this is to make the toast cal seem instant responsive.
  Fluttertoast.showToast(
    msg: '$a',
    toastLength: Toast.LENGTH_SHORT,
    gravity: ToastGravity.BOTTOM,
    backgroundColor: Colors.black87,
    textColor: Colors.yellow,
    fontSize: 14.0,
  );
}

void main() {
  SystemChrome.setSystemUIOverlayStyle(
    SystemUiOverlayStyle(
      statusBarColor: Color.fromRGBO(0, 0, 0, 0.0), //status bar is transparent
    ),
  );
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ROLL THE DICE',
      theme: ThemeData(
        brightness: Brightness.dark,
      ),
      home: MyHomePage(title: 'ROLL THE DICE'),
      debugShowCheckedModeBanner: false,
    );
  }
}

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

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

class _MyHomePageState extends State<MyHomePage> {
  Dice2D dice1 = new Dice2D(
    size: 300.0,
    borderWidth: 5.0,
    displayInt: 2,
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Center(
            child: Text(
          widget.title,
        )),
      ),
      body: Column(
        children: <Widget>[
          SliderDiceSize(
            minValue: 100.0,
            maxValue: 300.0,
            title: "Set the size of dice:",
            dice: dice1,
            titleColor: Colors.yellow,
          ),
          SliderBorderWidth(titleColor: Colors.yellow,title: "Set the border width of dice:",dice: dice1,minValue: 1.0,maxValue: 10.0,),
          Expanded(child: Center(child: dice1)),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          //function to display the number on dice as a toast
          showToastText(dice1.getDisplay());
        },
        backgroundColor: Colors.yellow,
        tooltip: "Show the number.",
        child: Icon(Icons.message),
      ),
    );
  }
}

dice2D.dart

    import 'package:flutter/material.dart';
import 'dart:math';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:vibration/vibration.dart';

void vibrateDiceRolling() {
  Vibration.cancel();
  Vibration.vibrate(duration: 50); //default is 500 ms
}

void showToastRolling() {
  Fluttertoast
      .cancel(); //to clear all scheduled toast call ; this is to make the toast call seem instant responsive.
  Fluttertoast.showToast(
    msg: "Roger that!",
    toastLength: Toast.LENGTH_SHORT,
    gravity: ToastGravity.BOTTOM,
    backgroundColor: Colors.black87,
    textColor: Colors.white70,
    fontSize: 14.0,
  );
}

class paintDice2D extends StatelessWidget {
  @override
  @required
  final int display;
  @required
  final double borderWidth;
  @required
  final Color diceColor;
  @required
  final double diceSize;

  paintDice2D(
      {Key key, this.diceSize, this.display, this.borderWidth, this.diceColor})
      : super(key: key);

  Widget drawEmptyBox() {
    return Center(
      child: Container(),
    );
  }

  Widget drawCircleDot() {
    return Center(
      child: Container(
        decoration: BoxDecoration(shape: BoxShape.circle, color: diceColor),
      ),
    );
  }

  Widget build(BuildContext context) {
    double divSize = (diceSize - 2 * borderWidth) / 3;
    return Container(
      decoration: BoxDecoration(
        borderRadius: BorderRadius.all(Radius.circular(10.0)),
        border: Border.all(
            color: diceColor, width: borderWidth, style: BorderStyle.solid),
      ),
      height: diceSize,
      width: diceSize,
      child: Row(
        children: <Widget>[
          Column(
            children: <Widget>[
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: (display == 3 ||
                            display == 4 ||
                            display == 5 ||
                            display == 6) ==
                        true
                    ? drawCircleDot()
                    : drawEmptyBox(), // condition == true ?  {code for true } : {code for false}
              ),
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child:
                    (display == 6) == true ? drawCircleDot() : drawEmptyBox(),
              ),
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: (display == 2 ||
                            display == 4 ||
                            display == 5 ||
                            display == 6) ==
                        true
                    ? drawCircleDot()
                    : drawEmptyBox(),
              ),
            ],
          ),
          Column(
            children: <Widget>[
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: drawEmptyBox(),
              ),
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: (display == 1 || display == 3 || display == 5) == true
                    ? drawCircleDot()
                    : drawEmptyBox(),
              ),
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: drawEmptyBox(),
              ),
            ],
          ),
          Column(
            children: <Widget>[
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: (display == 2 ||
                            display == 4 ||
                            display == 5 ||
                            display == 6) ==
                        true
                    ? drawCircleDot()
                    : drawEmptyBox(),
              ),
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child:
                    (display == 6) == true ? drawCircleDot() : drawEmptyBox(),
              ),
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: (display == 3 ||
                            display == 4 ||
                            display == 5 ||
                            display == 6) ==
                        true
                    ? drawCircleDot()
                    : drawEmptyBox(),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

class Dice2D extends StatefulWidget {
  @override
  @required
  double size;
  @required
  double borderWidth;
  @required
  int displayInt;

  Dice2D({
    Key key,
    this.size,
    this.borderWidth,
    this.displayInt,
  }) : super(key: key);

  int getDisplay() {
    return this.displayInt;
  }

  Dice2DState createState() {
    return new Dice2DState();
  }
}

class Dice2DState extends State<Dice2D> {
  @override
  Widget build(BuildContext context) {
    int nextDisplay = Random().nextInt(6) + 1;
        void rollDice() {
            setState(() {
                widget.displayInt = nextDisplay;
                nextDisplay = Random().nextInt(6) + 1;
                showToastRolling();
                vibrateDiceRolling();
            });
        }

        return FlatButton(
            onPressed: () {
                rollDice();
            },
            padding: EdgeInsets.all(0.0),
            child: paintDice2D(
                display: widget.displayInt,
                borderWidth: widget.borderWidth,
                diceSize: widget.size,
                diceColor: Colors.yellow,
            ),
        );
    }
  }


class SliderDiceSize extends StatefulWidget {
  @required final String title;
  @required Dice2D dice;
  @required final double minValue;
  @required final double maxValue;
  @required final Color titleColor;

  SliderDiceSize({Key key, this.title,  this.dice, this.titleColor, this.maxValue, this.minValue}):super(key:key);

  @override
  SliderDiceSizeState createState() {
    return new SliderDiceSizeState();
  }
}

class SliderDiceSizeState extends State<SliderDiceSize> {

  void setDiceSize(double a) {
    setState(() {
      int diceint = widget.dice.getDisplay(); //**
      widget.dice.displayInt = diceint; //**
      widget.dice.size = a; //**
    });
  }

  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: new Text(
            widget.title,
            style: TextStyle(color: widget.titleColor, fontSize: 16.0),
          ),
        ),
        Container(
          child: new Slider(
            value: widget.dice.size, //**
            onChanged: (double value) => setDiceSize(value), //**
            max: widget.maxValue,
            min: widget.minValue,
            activeColor: Colors.grey,
            inactiveColor: Colors.white12,
          ),
        ),
      ],
    );
  }
}

class SliderBorderWidth extends StatefulWidget {
  @required
  final String title;
  @required
  Dice2D dice;
  @required final double minValue;
  @required final double maxValue;
  @required final Color titleColor;

  SliderBorderWidth(
      {Key key,
      this.dice,
      this.title,
      this.minValue,
      this.maxValue,
      this.titleColor});

  @override
  SliderBorderWidthState createState() {
    return new SliderBorderWidthState();
  }
}

class SliderBorderWidthState extends State<SliderBorderWidth> {
    void setBorderWidth(double a) {
    setState(() {
        int diceint = widget.dice.getDisplay();  //**
        widget.dice.borderWidth = a;  //**
    });}

  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: new Text(
          widget.title,
            style: TextStyle(color: widget.titleColor, fontSize: 16.0),
          ),
        ),
        Container(
          child: new Slider(
            value: widget.dice.borderWidth,  //**
            onChanged: (double value) => setBorderWidth(value),  //**
            max: widget.maxValue,
            min: widget.minValue,
            activeColor: Colors.grey,
            inactiveColor: Colors.white12,
          ),
        ),
      ],
    );
  }
}

编辑

以下是使用回调函数的新完整代码。我已经使用 ~~ 标记了更新的代码行。 之前滑块无法拖动的问题再次弹出。代码中的注释标记了我对导致问题的行的怀疑。

main.dart

导入'package:flutter/material.dart';

import 'package:do_dice/dice2D.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';

void showToastText(int a) {
  Fluttertoast
      .cancel(); //to clear all scheduled toast call ; this is to make the toast cal seem instant responsive.
  Fluttertoast.showToast(
    msg: '$a',
    toastLength: Toast.LENGTH_SHORT,
    gravity: ToastGravity.BOTTOM,
    backgroundColor: Colors.black87,
    textColor: Colors.yellow,
    fontSize: 14.0,
  );
}

void main() {
  SystemChrome.setSystemUIOverlayStyle(
    SystemUiOverlayStyle(
      statusBarColor: Color.fromRGBO(0, 0, 0, 0.0), //status bar is transparent
    ),
  );
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ROLL THE DICE',
      theme: ThemeData(
        brightness: Brightness.dark,
      ),
      home: MyHomePage(title: 'ROLL THE DICE'),
      debugShowCheckedModeBanner: false,
    );
  }
}

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

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

class _MyHomePageState extends State<MyHomePage> {
  Dice2D dice1 = new Dice2D(
    size: 300.0,
    borderWidth: 5.0,
    displayInt: 2,
  );

//~~ added this function to serve as callback
updateDiceSize(Dice2D dice,double size){
    setState((){  
        dice.size = size;
    });
 }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Center(
            child: Text(
          widget.title,
        )),
      ),
      body: Column(
        children: <Widget>[
          SliderDiceSize(updateDiceSizeCallback: updateDiceSize(dice1,dice1.size),  //~~passing the callback
            minValue: 100.0,
            maxValue: 300.0,
            title: "Set the size of dice:",
            dice: dice1,
            titleColor: Colors.yellow,
          ),
          Expanded(child: Center(child: dice1)),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          //function to display the number on dice as a toast
          showToastText(dice1.getDisplay());
        },
        backgroundColor: Colors.yellow,
        tooltip: "Show the number.",
        child: Icon(Icons.message),
      ),
    );
  }
}

Dice2D.dart

import 'package:flutter/material.dart';
import 'dart:math';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:vibration/vibration.dart';

void vibrateDiceRolling() {
  Vibration.cancel();
  Vibration.vibrate(duration: 50); //default is 500 ms
}

void showToastRolling() {
  Fluttertoast
      .cancel(); //to clear all scheduled toast call ; this is to make the toast call seem instant responsive.
  Fluttertoast.showToast(
    msg: "Roger that!",
    toastLength: Toast.LENGTH_SHORT,
    gravity: ToastGravity.BOTTOM,
    backgroundColor: Colors.black87,
    textColor: Colors.white70,
    fontSize: 14.0,
  );
}

class PaintDice2D extends StatelessWidget {
  @override
  @required
  final int display;
  @required
  final double borderWidth;
  @required
  final Color diceColor;
  @required
  final double diceSize;

  PaintDice2D(
      {Key key, this.diceSize, this.display, this.borderWidth, this.diceColor})
      : super(key: key);

  Widget drawEmptyBox() {
    return Center(
      child: Container(),
    );
  }

  Widget drawCircleDot() {
    return Center(
      child: Container(
        decoration: BoxDecoration(shape: BoxShape.circle, color: diceColor),
      ),
    );
  }

  Widget build(BuildContext context) {
    double divSize = (diceSize - 2 * borderWidth) / 3;
    return Container(
      decoration: BoxDecoration(
        borderRadius: BorderRadius.all(Radius.circular(10.0)),
        border: Border.all(
            color: diceColor, width: borderWidth, style: BorderStyle.solid),
      ),
      height: diceSize,
      width: diceSize,
      child: Row(
        children: <Widget>[
          Column(
            children: <Widget>[
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: (display == 3 ||
                            display == 4 ||
                            display == 5 ||
                            display == 6) ==
                        true
                    ? drawCircleDot()
                    : drawEmptyBox(), // condition == true ?  {code for true } : {code for false}
              ),
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child:
                    (display == 6) == true ? drawCircleDot() : drawEmptyBox(),
              ),
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: (display == 2 ||
                            display == 4 ||
                            display == 5 ||
                            display == 6) ==
                        true
                    ? drawCircleDot()
                    : drawEmptyBox(),
              ),
            ],
          ),
          Column(
            children: <Widget>[
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: drawEmptyBox(),
              ),
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: (display == 1 || display == 3 || display == 5) == true
                    ? drawCircleDot()
                    : drawEmptyBox(),
              ),
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: drawEmptyBox(),
              ),
            ],
          ),
          Column(
            children: <Widget>[
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: (display == 2 ||
                            display == 4 ||
                            display == 5 ||
                            display == 6) ==
                        true
                    ? drawCircleDot()
                    : drawEmptyBox(),
              ),
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child:
                    (display == 6) == true ? drawCircleDot() : drawEmptyBox(),
              ),
              Container(
                width: divSize,
                height: divSize,
                padding: EdgeInsets.all(divSize / 5),
                child: (display == 3 ||
                            display == 4 ||
                            display == 5 ||
                            display == 6) ==
                        true
                    ? drawCircleDot()
                    : drawEmptyBox(),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

class Dice2D extends StatefulWidget {
  @override
  @required
  double size;
  @required
  double borderWidth;
  @required
  int displayInt;

  Dice2D({
    Key key,
    this.size,
    this.borderWidth,
    this.displayInt,
  }) : super(key: key);

  int getDisplay() {
    return this.displayInt;
  }

  Dice2DState createState() {
    return new Dice2DState();
  }
}

class Dice2DState extends State<Dice2D> {
  @override
  Widget build(BuildContext context) {
    int nextDisplay = Random().nextInt(6) + 1;
        void rollDice() {
            setState(() {
                widget.displayInt = nextDisplay;
                nextDisplay = Random().nextInt(6) + 1;
                showToastRolling();
                vibrateDiceRolling();
            });
        }

        return FlatButton(
            onPressed: () {
                rollDice();
            },
            padding: EdgeInsets.all(0.0),
            child: PaintDice2D(
                display: widget.displayInt,
                borderWidth: widget.borderWidth,
                diceSize: widget.size,
                diceColor: Colors.yellow,
            ),
        );
    }
  }


class SliderDiceSize extends StatefulWidget {
  @required final String title;
  @required Dice2D dice;
  @required final double minValue;
  @required final double maxValue;
  @required final Color titleColor;
  @required Function updateDiceSizeCallback;  //~~
  SliderDiceSize({Key key, this.title,  this.dice, this.titleColor, this.maxValue, this.minValue,this.updateDiceSizeCallback}):super(key:key);  //~~

  @override
  SliderDiceSizeState createState() {
    return new SliderDiceSizeState();
  }
}

class SliderDiceSizeState extends State<SliderDiceSize> {
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: new Text(
            widget.title,
            style: TextStyle(color: widget.titleColor, fontSize: 16.0),
          ),
        ),
        Container(
          child: new Slider(
            value: widget.dice.size,
            onChanged: (double value) => widget.updateDiceSizeCallback, //~~ I believe something needs to change here for slider to be able to drag.
            max: widget.maxValue,
            min: widget.minValue,
            activeColor: Colors.grey,
            inactiveColor: Colors.white12,
          ),
        ),
      ],
    );
  }
}

因为这是我在这里的第一个问题,我为混乱的代码和变量名道歉。

【问题讨论】:

  • 你能分享完整的代码/回购吗?也许我可以稍后再检查。
  • 我包含了完整的代码。顺便说一句,我在 SliderDiceSizeState 类(由 ** 标记)中搞砸了一点,并以某种方式让滑块能够拖动。但是新的问题出现了。当滑块被拖动时,它不会更新 Dice2D 对象的状态,但是当点击骰子本身(Dice2DState 中的函数 rolldice())时,它会根据滑块设置的值设置它的新大小。我应该编辑问题本身吗?
  • 我在答案中添加了一个示例。也许这会让事情更清楚。

标签: flutter slider


【解决方案1】:

您正在保存和使用小部件内部的属性,而不是状态类。 据我了解StatefulWidgetwidget 就像StatelessWidget。实际的state 应该在StatefulWidget 创建的State&lt;&gt; 类中。

尝试将骰子的属性 (Dice2D) 添加到实际的状态类中。

[编辑]

好的,我仔细查看了您的代码,我认为您没有更新正确的State。 您的滑块仅更新自己的 State(这是 setState() 所做的)。但他们应该更新他们的父母State (_MyHomePageState),因为这将触发MyHomePageWidget 用新的State 重建。 您的Die 在单击它时正在正确重建,因为这会触发Dice2DState 更新它自己的状态,这确实会触发 Dice2D 小部件的重建。

这就是问题所在。现在如何解决这个问题。您需要一种在_MyHomePageState 上触发setState() 的方法。有不同的方法可以做到这一点。但是因为你只是在尝试一些东西,所以我建议你使用回调。

在您的_MyHomePageState 中添加以下函数:

// Could also be separate functions for each property
updateDice({double size, double borderWidth, int displayInt}) {
    setState(() {
     if(size != null) dice1.size = size;
     if(borderWidth != null) dice1.borderWidth = borderWidth;
     if(displayInt != null) dice1.displayInt = displayInt; 
    });
  }

这将用于更新Dice

您的滑块将不得不使用它,因此将此函数作为回调传递给滑块的构造函数: SliderBorderWidth(updateDice ... rest of your params ...)

并将其存储在您的滑块小部件中: Function updateDiceCallback

more about passing functions here

现在您的滑块可以使用此回调来更新骰子的状态。 因为你的骰子的状态现在被管理在更高的层次结构中,所以你的骰子小部件应该是StatelessWidget,因为它无论如何都会被重绘并且只是一个视觉表示。 您还应该将UpdateDice-callback 传递给它,以便您可以将其连接到OnPressed 事件或其他东西并使其更新号码。

我希望这对你有意义。我试图修复您的代码,但我认为您需要了解状态更好地工作的方式。我将为您创建一个示例并添加它。

[样本]

试试这个,也许它会帮助你理解。就在新项目的 main.dart 中过去了。

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:math';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ROLL THE DICE',
      theme: ThemeData(
        brightness: Brightness.dark,
      ),
      home: MyHomePage(title: 'ROLL THE DICE'),
    );
  }
}

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

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

class _MyHomePageState extends State<MyHomePage> {
  Dice2D dice1 = new Dice2D(
    size: 150.0,
    displayInt: 2,
  );

  updateDice({double size, int displayInt}) {
    setState(() {
     if(size != null) dice1.size = size;
     if(displayInt != null) dice1.displayInt = displayInt; 
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Center(
            child: Text(
          widget.title,
        )),
      ),
      body: Column(
        children: [
          Slider(
            value: dice1.size,
            min: 100.0,
            max: 200.0,
            onChanged: (value){
            updateDice(size: value);
          },),
          DiceWidget(dice1.size, dice1.displayInt, updateDice),
        ],
      ),
    );
  }
}

class DiceWidget extends StatelessWidget {

  final int _number;
  final double _size;
  final Function _onPressed;

  DiceWidget(this._size, this._number, this._onPressed);

  @override
  Widget build(BuildContext context) {
    return Center(child: RaisedButton(
      onPressed: (){
        _onPressed(displayInt: Random().nextInt(5)+1);
      },
      child: Text("$_number", style: TextStyle(fontSize: _size),)),);
  }
}

class Dice2D {
  var size;
  var displayInt;

  Dice2D({this.size,this.displayInt});
}

【讨论】:

  • 我可以建议详细说明一下“如何?”和“为什么?”。
  • 这更像是一个建议,但我会详细说明。
  • 要小心,如果你给人的印象是它更像是一个建议而不是一个自信的答案,那么你可能会发现一些“应该是评论”的标志。
  • 我明白你的建议。但是如何在 main.dart 中创建 Dice2D 类的对象?
  • 是的,它有效!我理解更新父小部件状态以触发子小部件状态更改的概念。但这让我相信我们不能从完全不相关的兄弟 classB 触发 classA 的状态。这个假设有多少是正确的?如果有办法实现这一点,我想实现它而不是拥挤 main.dart 代码。感谢您对像我这样的新手的耐心。
猜你喜欢
  • 2019-01-31
  • 1970-01-01
  • 2017-04-26
  • 1970-01-01
  • 2016-01-28
  • 2022-11-21
  • 1970-01-01
  • 1970-01-01
  • 2020-04-15
相关资源
最近更新 更多