Ограничение макета, чтобы он не выходил за границы с помощью позиционированного виджета
В настоящее время я работаю над макетом, который отображает
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
поскольку дочерний элемент макета вызывает исключение.