在构建过程中获取Widget的位置和大小



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

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

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;
}

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;
}

最新更新