Flutter - 在应用交互中生成

Flutter - Generate in app interactivity

我有点迷失在 Flutter 上生成交互性。

我正在尝试使点击 FlatButtons 的值如上所示,并按照点击的顺序。

例如,点击数字 1,然后 2, 1, 1, 1 和最后 2 应该出现 $ 12111,记得相当多。

点击退格图标删除最后一个进入列表的号码。

我不知道在 类 之间生成此通信。

你能帮帮我吗?我正在尝试使用 StatefulWidget,但没有成功。

下面我留下了生成上述屏幕的代码。

main.dart

import "package:flutter/material.dart";

void main() {
  runApp(new KeyboardApp());
}

class KeyboardApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new ListView  (
        children: <Widget>[
          new Number(),
          new Keyboard(),
        ],
      ),
    );
  }  
}

class NumberState extends StatefulWidget {
  NumberList createState() => new NumberList();
}

class NumberList extends State<NumberState> {
  List<String> numbers = <String>[];
  String number;

  @override
  Widget build(BuildContext context) {
    number = this.numbers.join('');
    return new Text(
      this.number,
      style: new TextStyle(
        fontFamily: 'Roboto',
        color: new Color(0xFFFFFFFF),
        fontSize: 45.0
      )
    ); 
  }
}

class Number extends StatelessWidget {
  final Color color = new Color(0xFFE57373);

  @override
  Widget build(BuildContext context) {
    return new Container(
      height: 145.0,
      child: new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          new Container(
            padding: new EdgeInsets.only(right: 16.0, top: 35.0),
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                new Text(
                  '$  ',
                  style: new TextStyle(
                    fontFamily: 'Roboto',
                    color: new Color(0xFFFFFFFF),
                    fontSize: 20.0
                  )
                ),
                new NumberState(),
              ],
            )
          )
        ],
      ),
      color: color,
    );
  }
}

class Keyboard extends StatelessWidget {
  final Color color = new Color(0xFFE57373);

  var list = new NumberList().numbers;
  @override
  Widget build(BuildContext context) {
    return new Container(
      padding: new EdgeInsets.only(right: 15.0, left: 15.0, top: 47.0, bottom: 20.0),
      child: new Column(
        children: <Widget>[
          new Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              new FlatButton(
                textColor: color,
                child: new Text(
                  '1',
                  style: new TextStyle(
                    fontSize: 35.0
                  ),
                ),
                onPressed: () {
                  this.list.add('1');
                },
              ),
              new FlatButton(
                textColor: color,
                child: new Text(
                  '2',
                  style: new TextStyle(
                    fontSize: 35.0
                  ),
                ),
                onPressed: () {
                  this.list.add('2');
                },
              ),
              new FlatButton(
                textColor: color,
                child: new Icon(
                  Icons.backspace,
                  size: 35.0
                ),
                onPressed: () {
                  this.list.removeLast();
                },
              ),
            ],
          ),
        ],
      ),
    );
  }
}

查看 Flutter interactivity tutorial。在较高级别(嘿),您的问题是您试图将状态存储在小部件树的叶子中。您应该将您的状态存储在树中更高的位置,然后将其传递给 children.

下面的例子使用了ValueNotifier but you can also pass state around using streams, callbacks, or even Firebase Database.

import "package:flutter/material.dart";

void main() {
  runApp(new KeyboardApp());
}

class KeyboardApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  HomePageState createState() => new HomePageState();
}

class HomePageState extends State<HomePage> {
  ValueNotifier<List<int>> numbers = new ValueNotifier<List<int>>(<int>[]);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new ListView  (
        children: <Widget>[
          new NumberDisplay(numbers: numbers),
          new Keyboard(numbers: numbers),
        ],
      ),
    );
  }
}

class NumberDisplay extends AnimatedWidget {
  NumberDisplay({ this.numbers }) : super(listenable: numbers);
  final ValueNotifier<List<int>> numbers;

  final Color _color = new Color(0xFFE57373);

  @override
  Widget build(BuildContext context) {
    return new Container(
      height: 145.0,
      child: new Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          new Container(
            padding: new EdgeInsets.only(right: 16.0, top: 35.0),
            child: new Row(
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                new Text(
                  '$  ',
                  style: new TextStyle(
                    fontFamily: 'Roboto',
                    color: new Color(0xFFFFFFFF),
                    fontSize: 20.0
                  )
                ),
                new Text(
                  this.numbers.value.join(''),
                  style: new TextStyle(
                    fontFamily: 'Roboto',
                    color: new Color(0xFFFFFFFF),
                    fontSize: 45.0
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
      color: _color,
    );
  }
}

class Keyboard extends StatelessWidget {
  Keyboard({ this.numbers });
  final ValueNotifier<List<int>> numbers;

  final Color _color = new Color(0xFFE57373);

  @override
  Widget build(BuildContext context) {
    return new Container(
      padding: new EdgeInsets.only(right: 15.0, left: 15.0, top: 47.0, bottom: 20.0),
      child: new Column(
        children: <Widget>[
          new Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: <Widget>[
              new FlatButton(
                textColor: _color,
                child: new Text(
                  '1',
                  style: new TextStyle(
                    fontSize: 35.0
                  ),
                ),
                onPressed: () {
                  numbers.value = new List.from(numbers.value)..add(1);
                },
              ),
              new FlatButton(
                textColor: _color,
                child: new Text(
                  '2',
                  style: new TextStyle(
                    fontSize: 35.0
                  ),
                ),
                onPressed: () {
                  numbers.value = new List.from(numbers.value)..add(2);
                },
              ),
              new FlatButton(
                textColor: _color,
                child: new Icon(
                  Icons.backspace,
                  size: 35.0
                ),
                onPressed: () {
                  numbers.value = new List.from(numbers.value)..removeLast();
                },
              ),
            ],
          ),
        ],
      ),
    );
  }
}