Flutter 笔记

192 阅读1分钟

Flutter笔记

RelayoutBoundary优化

当一个节点满足如下条件之一时,该节点会被标记为RelayoutBoundary,子节点的大小变化不会影响到父节点的布局.

  • parentUsesSize = false: 父节点的布局不依赖当前节点的大小.
  • sizedByParent = true: 当前节点大小由父节点决定;
  • constraints.isTight: 大小为确定的值,即宽高的最大值等于最小值.

获取组件的大小和位置

GlobalKey _key = GlobalKey();
Size size;
Offset offset;

getValue() {
  RenderBox renderBox = _key.currentContext.findRenderObject();
  setState(() {
    size = renderBox.size;
    offset = renderBox.localToGlobal(Offset.zero);
  });
}

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Container(
      color: Colors.blue,
      alignment: Alignment.center,
      child: Container(
        key: _key,
        width: 200,
        height: 200,
        color: Colors.red,
        alignment: Alignment.center,
        child: Text('$size\n$offset', style: TextStyle(fontSize: 20),),
      ),
    ),
    floatingActionButton: FloatingActionButton(
      child: Icon(Icons.add),
      onPressed: getValue,
    ),
  );
}

使用CustomPaint获取组件大小(不使用GlobalKey)

RepaintBoundary(
  child: CustomPaint(
    painter: _SizePaint(
      onSize: _getSize
    ),
    child: Container(
      color: Colors.green,
      child: Text(
        'Hello World',
        style: TextStyle(fontSize: 30),
      ),
    ),
  ),
)

void _getSize(Size value) {
  WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
    setState(() {
      textSize = value;
    });
  });
}

class _SizePaint extends CustomPainter {
  Size _size = Size.zero;
  final ValueChanged<Size> onSize;

  _SizePaint({this.onSize});

  @override
  void paint(Canvas canvas, Size size) {
    Log.info('paint: $size', StackTrace.current);
    if(size != _size) {
      onSize.call(size);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return false;
  }
}