0

I am making a screen that has a shelf image along with a plus icon overlaying the entire image with a dotted border. I want to make the dotted border take up the entire space allowed by the largest child of the stack (the image). I also want the size of the dotted border and the plus icon always maintain a constant ratio. Here is my code:

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),)),
      ]),
      ],
    ));
  }
}

I do not want to use padding since that will make my app unresponsive. I have tried setting width and height of the container and the size of the icon to double.infinity and also added BoxConstraints.expand() in the constraints attribute of the container. Everytime it returns an error. This is my current output:

enter image description here

I want this: enter image description here (The plus could be bigger)

1
  • You need to set a height for image. Then you can add a container with same height with transparent background and dotted border. And this dotted border container will be in a Stack also.
    – Aks
    Commented Jun 26 at 14:03

2 Answers 2

1

You could use Positioned widget to force the dotted container to fill the entire stack:

Positioned.fill(
child:  DottedBorder(child: Container(child: const Icon(Icons.add),)),
)

For DottedBorder that you have made, i suggest to let it decide how large is the border width and the icon size according to the space it's represented in , that can be done using 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
}
) 

it's preferable to encapsulate the icon within the dotted widget not to pass it as a child.

3
  • Thanks for the answer, it would be great if you could also tell me how to fix the size of the plus icon and the border in a certain ratio. Commented Jun 26 at 15:49
  • @SanchitBatra , look at updates
    – A-E
    Commented Jun 26 at 17:51
  • But i am already following this format and this code is solely the mobile layout. I want the size to dynamically change like that of the image Commented Jun 27 at 3:58
0

You need to restrict the hight of the Stack since it is in a column and you want one of the child to be as big as possible.

AspectRatio could be a good choice here, Since the image doesn't change, and you know its dimension.

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,
                    ),
                  ),
                ),
              ),
            )
          ],
        ),
      ),
    ],
  );
3
  • Thanks for the answer, it would be great if you could also tell me how to fix the size of the plus icon and the border in a certain ratio. Commented Jun 26 at 15:49
  • I have update the code to include the sizing of the plus sign Commented Jun 27 at 14:15
  • The FractionallySizedBox change the position and FittedBox return error. Commented Jun 29 at 10:55

Not the answer you're looking for? Browse other questions tagged or ask your own question.