Home Articles

如何在垂直(高度)和水平(宽度)方向上实现窗口小部件的扩展

Asked
Viewed 484 times
5

下面的代码列出了一个图表,我需要在图表中实现图表在垂直(高度)和水平(宽度)方向上的扩展 . 建议的方法(例如https://docs.flutter.io/flutter/widgets/Row-class.html)是在 RowColumn 中使用 Expanded .

我试图扩展的图表小部件扩展 CustomPaint ,没有子节点,所有内容都在 CustomPainter.paint(canvas, size) 上使用 CustomPainter 在画布上绘制 .

这段代码

return new Scaffold(
  appBar: new AppBar(
    title: new Text(widget.title),
  ),
  body: new Center(    
    child: new Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        new Text(
          'vvvvvvvv:',
        ),
        new RaisedButton(
          color: Colors.green,
          onPressed: _chartStateChanger,
        ),
        new Text(
          'vvvvvvvv:',
        ),    
        new Expanded( // Expanded in Column, no expansion vertically 
          child: new Row(
            children: [
              new Text('>>>'),    
              new Expanded(// Expanded in Row, expands horizontally
                child: new Chart(  // extends CustomPaint
                  // size: chartLogicalSize,
                  painter: new ChartPainter( // extends CustomPainter
                    chartData: _chartData,
                    chartOptions: _chartOptions,
                  ),
                ),
              ),
              new Text('<<<'),
            ],
          ),  // row
        ),
        new Text('^^^^^^:'),
        new RaisedButton(
          color: Colors.green,
          onPressed: _chartStateChanger,
        ),
      ],
    ),
  ),
);

结果如下所示:(为简洁起见,未显示ChartPainter的代码)
result of the above code

ChartPainter.paint(canvas, size) 内部有一个 print() 打印尺寸 .

print(“### Size:paint():传递size = $ ”);

上面的paint-> print的结果是:

I / flutter(4187):###尺寸:paint():传递尺寸=尺寸(340.0,0.0)

打印与图像一起显示,行级别的宽度扩展已传递到 CustomPainter.print(canvas, size) (宽度= 340.0),但列上的高度扩展未传递到自定义画家打印(高度= 0.0) . 虽然结果显示行确实得到了它的扩展高度,但如果没有在行内传递到 CustomPainter - 0高度被接收 .

我还需要改变什么来实现高度扩展?

谢谢

2 Answers

  • 11

    有一种比嵌套 RowExpendedColumn 小部件更好的方法 . 您可以将 Container 小部件与 Constraints 一起使用到 BoxConstraints.expend() .

    这是我的小部件的代码捕捉 .

    Widget build(BuildContext context) {
          return Container(
            constraints: BoxConstraints.expand(), 
            child: FutureBuilder(
              future: loadImage(),
              builder: (BuildContext context, AsyncSnapshot<ui.Image> snapshot) {
                switch(snapshot.connectionState) {
                  case ConnectionState.waiting : 
                    return Center(child: Text("loading..."),);
                  default:
                    if (snapshot.hasError) {
                      return Center(child: Text("error: ${snapshot.error}"),);
                    } else {
                      return ImagePainter(image: snapshot.data);
                    }
                  }
                },
              ),
          );
        }
    
  • 1

    这是针对您所看到的问题的简化测试用例 . 解决方案是给你的 Row crossAxisAlignment CrossAxisAlignment.stretch . 否则它将尝试确定 CustomPaint 的内在高度,因为它没有孩子,所以它为零 .

    import 'package:flutter/material.dart';
    
    // from https://stackoverflow.com/questions/45875334/how-to-achieve-expansion-of-a-widget-in-both-vertical-height-and-horizontal-w
    
    class MyCustomPainter extends CustomPainter {
      @override
      void paint(Canvas canvas, Size size) {
        // NOT using crossAxisAlignment: CrossAxisAlignment.stretch => width = 222.0, height=0.0
        // using crossAxisAlignment: CrossAxisAlignment.stretch     => width = 222.0, height=560.0
        print("width = ${size.width}, height=${size.height}");
        canvas.drawRect(Offset.zero & size, new Paint()..color = Colors.blue);
      }
    
      @override
      bool shouldRepaint(MyCustomPainter other) => false;
    }
    void main() {
      runApp(new MaterialApp(
        home: new Scaffold(
            body: new Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                new Text('Above Paint'),
                // Expanded - because we are in Column, expand the
                //            contained row's height
                new Expanded(
                  child: new Row(
                    // The crossAxisAlignment is needed to give content height > 0
                    //   - we are in a Row, so crossAxis is Column, so this enforces
                    //     to "stretch height".
                    crossAxisAlignment: CrossAxisAlignment.stretch,
                    children: <Widget>[
                      new Text('Left of Paint'),
                      // Expanded - because we are in Row, expand the
                      //           contained Painter's width
                      new Expanded(
                        child: new CustomPaint(
                          painter: new MyCustomPainter(),
                        ),
                      ),
                      new Text('Right of Paint'),
                    ],
                  ),
                ),
                new Text('Below Paint'),
              ],
            )
        ),
      ));
    }
    

Related