Flutter获取Widget信息
Flutter获取Widget
信息通过给Widget
设置一个GlobalKey
,通过GlobalKey
获取对应的RenderObject
来获取相应的信息。
获取RenderObject
RenderBox? renderBox = _widgetKey.currentContext?.findRenderObject() as RenderBox?;
获取Widget大小信息
Size = renderBox?.size;
获取Widget位置信息
Offset offset = renderBox?.localToGlobal(Offset.zero);
进入页面获取Widget信息
构造器或者init
方法执行的时候,context
还没有和state
进行关联,此时获取到的currentContext
必然是null
,因此要等到Widget
渲染完成后,才能正常获取。在Widget
渲染完成回调中即可通过上述方法正常获取。
@override
void initState() {
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
// 获取信息
});
super.initState();
}
完整代码
import 'dart:async';
import 'package:flutter/material.dart';
class GetWidgetInfoDemoPage extends StatefulWidget {
@override
_GetWidgetInfoDemoPageState createState() => _GetWidgetInfoDemoPageState();
}
class _GetWidgetInfoDemoPageState extends State<GetWidgetInfoDemoPage> {
late StreamController<String> _widgetsSizeInfoController;
late StreamController<String> _widgetsPositionInfoController;
final initInfo = "点击Logo获取信息";
final _widgetKey = GlobalKey();
void getInfo(){
RenderBox? renderBox = _widgetKey.currentContext?.findRenderObject() as RenderBox?;
_widgetsSizeInfoController.sink.add("宽:${renderBox?.size.width} 高:${renderBox?.size.height}");
final offset = renderBox?.localToGlobal(Offset.zero);
_widgetsPositionInfoController.sink.add("x: ${offset?.dx.toStringAsFixed(2)} y:${offset?.dy.toStringAsFixed(2)}");
}
@override
void initState() {
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
getInfo();
});
super.initState();
_widgetsSizeInfoController = StreamController();
_widgetsPositionInfoController = StreamController();
}
@override
void dispose() {
super.dispose();
_widgetsPositionInfoController.close();
_widgetsSizeInfoController.close();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("获取Widget信息"),
centerTitle: false,
),
body: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
// flutter logo
FlutterLogo(
size: 200,
key: _widgetKey,
),
// 信息
Container(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
title: const Text("位置信息"),
trailing: StreamBuilder<String>(
initialData: initInfo,
stream: _widgetsSizeInfoController.stream,
builder: (context, snapshot) => Text(snapshot.data??initInfo),
),
),
ListTile(
title: const Text("大小信息"),
trailing: StreamBuilder<String>(
initialData: initInfo,
stream: _widgetsPositionInfoController.stream,
builder: (context, snapshot) => Text(snapshot.data??initInfo),
),
),
SizedBox(height: 60,),
ElevatedButton(
child: Text("获取信息"),
onPressed: getInfo,
),
],
),
),
],
),
);
}
}