首页 > 解决方案 > 在构建期间获取 Widget 的位置和大小

问题描述

如何在build()方法期间获取小部件的大小和位置?在下面的代码中,我想在CustomPaint小部件中绘制矩形,该矩形居中并且是视口剩余区域的一定百分比,即小部件下方的所有内容Text,标记为(A)。我可以从中获得宽度MediaQuery,但是之后我将如何获得剩余的高度(A)?我必须知道Text小部件的位置。

这个答案不起作用,因为 Flutter 在尝试检索RenderBoxduring build() 时抛出异常。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('App')),
      body: Column(children: [
        Text('Test'), // (A) Get position of this
        CustomPaint(
          painter: DrawArea(MediaQuery.of(context).size),
          size: Size(1000, 800),
        ),
      ]),
    );
  }
}

class DrawArea extends CustomPainter {
  final Size viewportSize;

  DrawArea(this.viewportSize);

  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.black
      ..strokeWidth = 1
      ..style = PaintingStyle.stroke;

    double yOffset = (this.viewportSize.width - this.viewportSize.width * .95) / 2;
    canvas.drawRect(Rect.fromLTWH(yOffset, 0, this.viewportSize.width * .95, 800), paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

标签: flutterdart

解决方案


paint方法的第二个参数是小部件的大小CustomPaint。您只需要确保您的小部件尺寸合适。

CustomPaint占用 中的其余空间Column,您需要将其包装在一个Expanded小部件中:

      body: Column(children: [
        Text('Test'),
        Expanded(
          child: CustomPaint(
            painter: DrawArea(),
            size: Size.infinite, // make it as large as possible
          ),
        ),
      ]),

然后你可以size在你的自定义画家中使用传递的参数:

class DrawArea extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    var paint = Paint()
      ..color = Colors.black
      ..strokeWidth = 1
      ..style = PaintingStyle.stroke;

    double xOffset = size.width * 0.025
    double yOffset = size.height * 0.025
    canvas.drawRect(Rect.fromLTWH(xOffset, yOffset, size.width * .95, size.height * .95), paint);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

推荐阅读