android - Flutter:按下按钮时更改容器的高度

标签 android dart flutter

这里的问题是,在按下按钮更改 funArg 值后,Container 不会重绘自身,该按钮应该更改其高度,因为它已用于计算

代码如下:

这里是 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);
          })
        ],
      ),
    );
  }
}

这里是 fun.dart:

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

谢谢。

最佳答案

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


主要问题是您将 Plate 定义为有状态的小部件,并将 rectArg 存储在该状态中! PlateState 只启动一次,直到你离开屏幕,它不会在父部件重建时重新创建!

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 方法中您的 State,使用 widget 属性访问您的小部件的最终字段:

class ColoredCheckbox extends StatefulWidget {
  const ColoredCheckbox({Key key, this.color}) : super(key: key);

  // this is passed in from the parent, can change when the parent is rebuilt
  final Color color;

  @override
  State<StatefulWidget> createState() => ColoredCheckboxState();
}

class ColoredCheckboxState extends State<ColoredCheckbox> {
  // this is internal state, kept even when the parent is rebuilt
  bool checked = false;

  // build is called when:
  // - you call setState from this widget
  // - when the parent widget is rebuilt
  @override
  Widget build(BuildContext context) {
    return RaisedButton(
      child: Text(checked ? 'X' : '0'),
      // use "widget" to access the fields passed in from the parent
      color: widget.color,
      onPressed: () {
        // always call setState when changing internal state
        setState(() {
          checked = !checked;
        });
      },
    );
  }
}

关于android - Flutter:按下按钮时更改容器的高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51598255/

相关文章:

Android:如何在 onReceive 中将短信标记为已读

Android:asmack(已移植)还是 smack(已修补)?

java - 在eclipse上导入现有项目后突然报错ObjectSetting.java文件

flutter - 无法在 VSCode 上热重载

flutter - 发布请求正文未正确发送

flutter - ffmpeg : how to put only color overlay video or apply different type of color filter like instagram in video using ffmpeg

android - 关闭后如何在 ionic 框架中保存/加载 Web 应用程序设置?

Dart Polymer Paper with Chrome app -(内联脚本 CSP 问题)

flutter - Flutter 如何在文本字符串中使用引号?

flutter - 如何使用 async_redux 实现路由导航