Flutter获取Widget坐标

2,509 阅读1分钟

背景

在适配屏幕时,设计图纸以大屏方式输出,尺寸也是适用于大屏,针对类似iphone 6s等设备,原设计图纸不适用 针对小屏幕设备,通过滚动的方式来保证小屏幕设备功能的可用性。

适配方案

获取widget屏幕位置,设置视图的偏移量

import 'package:flutter/material.dart';

typedef Callback = Function(RenderBox renderBox, Offset offset);

///计算控件的位置
class WidgetPosition {
  late GlobalKey _globalKey;
  bool _stop = false;

  WidgetPosition(GlobalKey globalKey) {
    _globalKey = globalKey;
    _stop = false;
  }

  ///获取控件的位置
  void getWidgetPosition(Callback callback) {
    WidgetsBinding.instance?.addPersistentFrameCallback((_) {
      if (_stop) {
        debugPrint("页面渲染完毕已读取数值");
        return;
      }
      debugPrint("页面渲染完毕");
      RenderObject? _renderObj = _globalKey.currentContext?.findRenderObject();
      if (_renderObj != null) {
        _stop = true;
        RenderBox _renderBox = _renderObj as RenderBox;
        Offset _offset = _renderBox.localToGlobal(Offset.zero);
        callback(_renderBox, _offset);
        debugPrint("view Offset: $_offset");
        return;
      }
    });
  }
}

遇到的问题

WidgetsBinding.instance?.addPostFrameCallback((_){});

为什么不使用这个回调方法??? 原因:addPostFrameCallback在当前Frame绘制完后进行回调,并只会回调一次,会出现组件未绘制完成的场景

GlobalKey的作用

什么是GlobalKey

A key that is unique across the entire app.

该处用于标记控件

//手电筒控件全局key
final GlobalKey flashWidgetGlobalKey = GlobalKey();
Container(
  key: flashWidgetGlobalKey,
  width: MediaQuery.of(context).size.width,)