Как разместить CompositedTransformFollower в зависимости от размера его дочернего элемента? - PullRequest
1 голос
/ 06 мая 2020

Я использую CompositedTransformTarget и CompositedTransformFollower для отображения OverlayEntry. Как я могу расположить CompositedTransformFollower относительно CompositedTransformTarget, т.е. как выровнять его нижнюю часть по центру верхней части цели, чтобы отображать ее горизонтально по центру над целью, сохраняя при этом интерактивность (например, тесты попадания на ребенок должен работать)?

Я пытался вычислить offset, чтобы передать CompositedTransformFollower, но я не могу сделать правильный расчет, потому что в то время у меня нет размера ребенка.

Пример кода:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(brightness: Brightness.light),
      home: Scaffold(
        appBar: AppBar(title: Text('test')),
        body: Center(child: OverlayButton()),
      ),
    );
  }
}

class OverlayButton extends StatefulWidget {
  @override
  _OverlayButtonState createState() => _OverlayButtonState();
}

class _OverlayButtonState extends State<OverlayButton> {
  OverlayEntry _overlayEntry;
  final LayerLink _layerLink = LayerLink();
  bool _overlayIsShown = false;

  @override
  void dispose() {
    super.dispose();
    if (_overlayIsShown) {
      _hideOverlay();
    }
  }

  void _showOverlay() {
    if (_overlayIsShown) return;
    _overlayEntry = _createOverlayEntry();
    Overlay.of(context).insert(_overlayEntry);
    _overlayIsShown = true;
  }

  void _hideOverlay() {
    _overlayIsShown = false;
    _overlayEntry.remove();
  }

  @override
  Widget build(BuildContext context) {
    return CompositedTransformTarget(
      link: _layerLink,
      child: RaisedButton(child: Text('Open Overlay'), onPressed: _showOverlay),
    );
  }

  OverlayEntry _createOverlayEntry() {
    RenderBox renderBox = context.findRenderObject();
    var anchorSize = renderBox.size;
    return OverlayEntry(builder: (context) {
      // TODO: dynamically use the correct child width / height for
      // positioning us correctly on top + centered on the anchor
      var childWidth = 200.0;
      var childHeight = 40.0;
      var childOffset =
          Offset(-(childWidth - anchorSize.width) / 2, -(childHeight));
      return Row(
        children: <Widget>[
          CompositedTransformFollower(
            link: _layerLink,
            offset: childOffset,
            child: RaisedButton(
              child: Text('close'),
              onPressed: _hideOverlay,
            ),
          ),
        ],
      );
    });
  }
}
...