Ограничение макета, чтобы он не выходил за границы с помощью позиционированного виджета

В настоящее время я работаю над макетом, который отображает Positionedвиджет на весь экран. Он позиционируется рядом с обнаруженным штрих-кодом. Посмотрите на изображение ниже для примера.

Но когда штрих-код перемещается, чтобы закрыть левый край экрана, элементы пользовательского интерфейса частично отрисовываются за пределами экрана. Есть ли способ исправить это, не вычисляя, когда я выхожу за пределы каждого кадра?

Вот код, который я использую для настройки:

      Widget _buildImage() {
    return Container(
      constraints: const BoxConstraints.expand(),
      child: _controller == null
          ? const Center(
              child: Text(
                'Initializing Camera...',
                style: TextStyle(
                  color: Colors.green,
                  fontSize: 30.0,
                ),
              ),
            )
          : Stack(
              fit: StackFit.expand,
              children: <Widget>[
                CameraPreview(_controller!),
                _buildResults(),
                if (_scanResults.isNotEmpty)
                   _buildUIElements()

              ],
            ),
    );
  }

  Widget _buildUIElements() {
    Barcode barcode = _scanResults[0];
    final Size imageSize = Size(
      _controller!.value.previewSize!.height,
      _controller!.value.previewSize!.width,
    );
    var boundingBox = barcode.boundingBox!;
    var rect = scaleRect(rect: boundingBox, imageSize: imageSize, widgetSize: MediaQuery.of(context).size);
    return AnimatedPositioned(
      top: rect.bottom,
      left: rect.left,
      child: Card(
        child: Text('This is an amaizing product'),
      ),
      duration: const Duration(milliseconds: 500),
    );
  }

Может, есть способ лучше этого добиться?

Не обращайте внимания на чрезмерное использование ! все еще изучаю всю вещь о нулевой безопасности :)

РЕДАКТИРОВАТЬ 1: Как было предложено pskink, я посмотрел, как работают всплывающие подсказки во флаттере, и использовал SingleChildLayoutDelegate в сочетании с CustomSingleChildLayout и это отлично работает для отслеживания позиции, но теперь нет возможности анимировать это.

Мой класс делегата выглядит следующим образом:

      class CustomSingleChildDelegate extends SingleChildLayoutDelegate {

  CustomSingleChildDelegate ({
    required this.target,
    required this.verticalOffset,
    required this.preferBelow,
  });

  final Offset target;

  final double verticalOffset;

  final bool preferBelow;

  @override
  BoxConstraints getConstraintsForChild(BoxConstraints constraints) => constraints.loosen();

  @override
  Offset getPositionForChild(Size size, Size childSize) {
    return positionDependentBox(
      size: size,
      childSize: childSize,
      target: target,
      verticalOffset: verticalOffset,
      preferBelow: preferBelow,

    );
  }

  @override
  bool shouldRelayout(CustomSingleChildDelegate oldDelegate) {
    return target != oldDelegate.target
        || verticalOffset != oldDelegate.verticalOffset
        || preferBelow != oldDelegate.preferBelow;
  }
}

А затем обновил мою функцию построителя:

      return CustomSingleChildLayout(
        delegate: CustomSingleChildDelegate (target: rect.bottomCenter, verticalOffset: 20, preferBelow: true),
        child: Card(
            child: Text('This is an amaizing product'),
          ),
      )

Имея AnimatedPositioned поскольку дочерний элемент макета вызывает исключение.

0 ответов

Другие вопросы по тегам