颤动:按下按钮时更改容器的高度

时间:2018-07-30 16:16:47

标签: android dart flutter

这里的问题是,在通过按下按钮更改了funArg值之后,容器不会重绘自身,这应该更改其高度,因为它是在计算中使用的

这是代码:

这是main.dart:

import 'package:flutter/material.dart';
import 'package:sqaure/ui/fun.dart';

Widget rect0;


String rectArg = "20";


class Home extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new HomeState();
  }
}

class HomeState extends State<Home> {
  var list = ["20", "15"];

  Widget funTest() {
    setState(() {
      rectArg = list[1];
      rect0 = new Plate(rectArg);
    });
  }


  //final Color primaryColor = Colors.red;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("rect"),
        backgroundColor: Colors.red,
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          new Container(
            alignment: Alignment.topCenter,
            color: Colors.white,
            height: 245.0,
            child: new Stack(
              children: <Widget>[
                Center(
                  child: Padding(
                    padding: const EdgeInsets.only(left: 55.0),
                    child: Row(
                      children: <Widget>[
                        //plates
                        rect0 = new Plate(rectArg),
                      ],
                    ),
                  ),
                )
              ],
            ),
          ),
          new RaisedButton(onPressed: () {
            funTest();
            debugPrint(rectArg);
          })
        ],
      ),
    );
  }
}

这很有趣。飞镖:

import 'package:flutter/material.dart';

class Plate extends StatefulWidget {
  final String funArg2;
  @override
  State<StatefulWidget> createState() {
    return new PlateState(funArg2);
  }
[enter image description here][1]
  Plate(this.funArg2);
}

class PlateState extends State<Plate> {
  String funArg;
  @override
  Widget build(BuildContext context) {
    return Padding(
        padding: const EdgeInsets.all(3.0),
        child: Container(
          alignment: Alignment.center,
          color: Colors.redAccent,
          height:  funArg !=  "" ? (9.33 * double.parse(funArg) + 45) : 0.0,
          width: 29.0,
          child: new Text(
            funArg,
            style: new TextStyle(
              color: Colors.white,
              fontWeight: FontWeight.w600,
              fontSize: funArg.length > 4
                  ? 10.0
                  : funArg.length > 3 ? 14.0 : 19.0,
            ),
          ),
        ));
  }

  PlateState(this.funArg);
}

如您所见,容器的高度由里面的子文本确定。

screenshot

谢谢。

1 个答案:

答案 0 :(得分:1)

这是您的代码的固定版本和注释版本。请阅读评论!


主要问题是您将Plate定义为有状态的窗口小部件,并在该状态下存储了rectArgPlateState仅启动一次,直到您离开屏幕为止,在重建父窗口小部件时都不会重新创建它!

Plate实际上没有任何内部状态,因此应为StatelessWidget。您应该始终喜欢StatelessWidget。了解为什么对于Flutter开发至关重要!

import 'package:flutter/material.dart';

main() => runApp(MaterialApp(home: Home()));

class Home extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return new HomeState();
  }
}

// this seems to be a constant, so can put it outside of the class
// or alternatively inside, with "static const" modifier
const list = ["20", "15"];

class HomeState extends State<Home> {
  // stateful variables (things that change over time)
  // must be inside of your state class
  String rectArg = "20";

  // we can return void here!
  void funTest() {
    setState(() {
      // state is modified here. this triggers a rebuild/redraw
      // that means the build function is called again
      // note that we are only the storing the string value, NOT a widget!
      rectArg = list[1];
    });
  }

  // this is called every time you setState
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("rect"),
        backgroundColor: Colors.red,
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          new Container(
            alignment: Alignment.topCenter,
            color: Colors.white,
            height: 245.0,
            child: new Stack(
              children: <Widget>[
                Center(
                  child: Padding(
                    padding: const EdgeInsets.only(left: 55.0),
                    child: Row(
                      children: <Widget>[
                        // DO NOT SET VARIABLES FROM THE BUILD METHOD!
                        // this is bad:
                        // rect0 = new Plate(rectArg),
                        Plate(
                          funArg: rectArg,
                        ),
                      ],
                    ),
                  ),
                )
              ],
            ),
          ),
          new RaisedButton(onPressed: () {
            funTest();
            debugPrint(rectArg);
          })
        ],
      ),
    );
  }
}

// Plate is actually a StatelessWidget because it is not interactive and holds no internal state
// All the data (funArg) is passed in from the parent ==> StatelessWidget
// Always prefer stateless widgets!
// That means the widget is completely rebuilt every time the build() method is called in HomeState
class Plate extends StatelessWidget {
  // Use named constructor parameters and call the super constructor!
  // you can auto-generate the constructor with Android Studio
  const Plate({Key key, this.funArg}) : super(key: key);

  final String funArg;

  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(3.0),
      child: Container(
        alignment: Alignment.center,
        color: Colors.redAccent,
        height: funArg != "" ? (9.33 * double.parse(funArg) + 45) : 0.0,
        width: 29.0,
        child: new Text(
          funArg,
          style: new TextStyle(
            color: Colors.white,
            fontWeight: FontWeight.w600,
            fontSize: funArg.length > 4 ? 10.0 : funArg.length > 3 ? 14.0 : 19.0,
          ),
        ),
      ),
    );
  }
}

仅当您需要内部状态为StatefulWidget且还具有由父窗口小部件设置的构造函数参数(这是很常见的)时:在build的{​​{1}}方法内部,请使用State属性访问窗口小部件的最终字段:

widget