Flutter中获取Widget信息

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值