Flutter Positioned Widget not fixed depending size screen

3.3k views Asked by At

My problem concerns the Positioned Widget. I'd like to position Widgets that match with an ExactAssetImage location of a Container. The context is to apply a PDF sheet to mobile with many assets with a RadioButton/editText.

The fact is, if I don't specify a fixed width and height for the Container containing the image, the Positioned Widget will not have the same position but it will depend on the size screen of the device.

This means I can't use MediaQuery to force my Image to fill the screen.

Here's my Container with the Image:

class CustomDecoratedBox extends StatelessWidget {
  final Widget widget;
  final double width;
  final double height;
  String asset;

  CustomDecoratedBox({@required this.widget, this.height, this.width,this.asset});

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 5.0),
      child: Container(
        width: width,
        height: height,
        decoration: BoxDecoration(
            image: DecorationImage(
              image: ExactAssetImage(
                asset,
              ),
             fit: BoxFit.fill,
              alignment: Alignment.center,
            ),
            border: Border.all(color: Colors.black, width: 1),
            color: Colors.white),
        child: widget,),);}

And here's how i position the child's positioned widget (whithin a stack because the are plenty of it):

return CustomDecoratedBox(
          width: 360,
          height: 360,
          asset: 'assets/xxx.png',
          widget: Stack(
            children: [
              Positioned(
                bottom: 12,
                left: 16,
                child: CustomTextFieldSetup(
                  width: 50,
                  maxLength: 5,
                  keyboardType: TextInputType.number,
                  textEditingController: _textEditingController,
                ),
              ),

What would be according to you, the best way to answer this use case?

Thank you for your help

2

There are 2 answers

3
GrahamD On

In your CustomDecoratedBox class, try wrapping the container in a FittedBox widget. FittedBox should scale your container within the constraints of your screen size and, in doing so, retain your positions relative to the container dimensions.

0
Kephas36 On

Ok I have found a very good way that works for every size of screen with the LayoutBuilder. What I did is encapsulating 2 LayoutBuilder in each other.

The child one will base its constraints on its parent LayoutBuilder. but the trick is the width and the height you give to your parent, as it has the image in its decoration, you should use only maxWidth or maxHeight to provide the dimension, based on the ratio dimen of your image :

return LayoutBuilder(
      builder: (context, cons) => Center(
        child: Container(
  /// Here you size the container with the width for both height and width of 
  /// the container
          height: cons.maxWidth * 0.8839,
          width: cons.maxWidth,
          decoration: BoxDecoration(
              image: DecorationImage(
                image: AssetImage('assets/xxx.png'),
                fit: BoxFit.fitWidth,
              ),
              border: Border.all(color: Colors.black, width: 1),
              color: Colors.white),
          child: LayoutBuilder(builder: (context, constraints) {
            double diameter = constraints.maxWidth / 28;
            return Center(
              child: Stack(
                children: [
                   Positioned(
                    top: constraints.maxHeight / 3.45,
                    right: constraints.maxWidth / 28,
                    child: //ect...

then you give to your Positionned widgets params constraint value. Hope it will help for some of you