Я создаю экран с изображением полки и значком плюса, перекрывающим все изображение пунктирной рамкой. Я хочу, чтобы пунктирная граница занимала все пространство, отведенное самому большому дочернему элементу стека (изображению). Я также хочу, чтобы размер пунктирной границы и значка плюса всегда сохранял постоянное соотношение. Вот мой код:
import "package:dotted_border/dotted_border.dart";
import "package:flutter/cupertino.dart";
import "package:flutter/material.dart";
import "package:flutter/widgets.dart";
class Default extends StatefulWidget {
const Default({super.key});
@override
State<Default> createState() => _DefaultState();
}
class _DefaultState extends State<Default> {
Map Articles = {};
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Published", style: Theme.of(context).textTheme.headlineLarge),
Text("Drafts", style: Theme.of(context).textTheme.headlineLarge),
],),
Stack(
alignment: Alignment.center,
children: [
Center(
child: Container(
color: Colors.black,
child: const ColorFiltered(
colorFilter: ColorFilter.mode(
Color.fromARGB(76, 0, 0, 0), BlendMode.darken),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Expanded(child: Image(image: AssetImage("assets/images/shelf.png"))),
Expanded(child: Image(image: AssetImage("assets/images/shelf.png"))),
],
)))),
DottedBorder(child: Container(child: const Icon(Icons.add),)),
]),
],
));
}
}
Я не хочу использовать отступы, так как это приведет к тому, что мое приложение перестанет отвечать на запросы. Я попробовал установить width
и height
контейнера и размер значка на double.infinity
, а также добавил BoxConstraints.expand()
в атрибут ограничений контейнера. Каждый раз возвращает ошибку. Это мой текущий результат:
Я хочу это: (Плюс мог бы быть больше)
Вы можете использовать виджет Positioned, чтобы заставить пунктирный контейнер заполнить весь стек:
Positioned.fill(
child: DottedBorder(child: Container(child: const Icon(Icons.add),)),
)
Для DottedBorder
, который вы сделали, я предлагаю предоставить ему возможность решить, насколько велики border width
и icon size
в зависимости от пространства, в котором они представлены, это можно сделать с помощью LayoutBuilder
:
LayoutBuilder(
builder(context,constraints){
if (constraints.maxWidth > 400) // it's tablet
{
// set appropriate border width and icon size
}
else if (constraints.maxWidth > 900) // it's a PC
{
// set appropriate border width and icon size
}
else{ // it's a mobile
// set appropriate border width and icon size
}
// create your DottedWidget and return it based on the border width and the icon size
}
)
желательно инкапсулировать значок в пунктирный виджет, чтобы не передавать его как дочерний элемент.
Спасибо за ответ, было бы здорово, если бы вы также рассказали мне, как исправить размер значка плюса и границы в определенном соотношении.
@SanchitBatra, смотри обновления
Но я уже использую этот формат, и этот код предназначен исключительно для мобильных устройств. Я хочу, чтобы размер динамически менялся, как у изображения.
Вам необходимо ограничить высоту стека, поскольку он находится в столбце, и вы хотите, чтобы один из дочерних элементов был как можно большим.
AspectRatio
здесь может быть хорошим выбором, так как изображение не меняется, и вы знаете его размерность.
Column(
children: [
const SizedBox(height: 100),
AspectRatio(
aspectRatio: 1,
child: Stack(
children: [
Positioned.fill(
child: Image.asset("assets/bird.png"),
),
Container(
decoration: BoxDecoration(
border: Border.all(width: 5),
),
child: Center(
child: FractionallySizedBox(
widthFactor: 0.5,
heightFactor: 0.5,
child: FittedBox(
child: Icon(
Icons.add,
color: Colors.white,
),
),
),
),
)
],
),
),
],
);
Спасибо за ответ, было бы здорово, если бы вы также рассказали мне, как исправить размер значка плюса и границы в определенном соотношении.
Я обновил код, включив в него размер знака плюса.
FractionallySizedBox
меняет позицию и FittedBox
возвращает ошибку.
Вам нужно установить высоту изображения. Затем вы можете добавить контейнер той же высоты с прозрачным фоном и пунктирной границей. И этот контейнер с пунктирной границей также будет в стеке.