Home > Software engineering >  how to wrap buttons and expand to parent width on wrap
how to wrap buttons and expand to parent width on wrap

Time:05-17

I want a responsive expanded buttons when wrapped from a small screen.

This is how the 'emergency contact' and 'book again' button should look like when it can it can fit on the screen: (Ex: iPhone 13 Pro Max):

1

This is how the 'emergency contact' and 'book again' button should look like when it is wrapped and cannot fit on the screen: (Ex: iPhone 8):

2

But, what really happens now is like this:

3

The Code:

  Container(
                                  margin: const EdgeInsets.only(top: 5),
                                  alignment: Alignment.topLeft,
                                  child: Wrap(
                                    runAlignment: WrapAlignment.start,
                                    runSpacing: 2.5,
                                    spacing: 2.5,
                                    children: [
                                      Expanded(
                                          flex: 1,
                                          child: SizedBox(
                                              child: ElevatedButton(
                                                  style: ElevatedButton
                                                      .styleFrom(
                                                    primary: Colors.white,
                                                  ),
                                                  onPressed: () {
                                                    // ignore: avoid_print
                                                    print("Book Again");
                                                  },
                                                  child: const Text(
                                                    "Book Again",
                                                    style: TextStyle(
                                                        color:
                                                            Colors.black),
                                                  )))),
                                      Expanded(
                                          flex: 1,
                                          child: SizedBox(
                                            child: ElevatedButton(
                                                style: ElevatedButton
                                                    .styleFrom(
                                                        primary:
                                                            Colors.white),
                                                onPressed: () {
                                                  // ignore: avoid_print
                                                  print(
                                                      "Emergency contact");
                                                },
                                                child: const Text(
                                                  "Emergency Contact",
                                                  style: TextStyle(
                                                      color: Colors.black,
                                                      fontSize: 14),
                                                )),
                                          ))
                                    ],
                                  ),
                                )

What I try to is use Wrap on two expanded which contains a sizedbox that contains elevatedbutton.

I will appreciate any feedback.

CodePudding user response:

I usually use LayoutBuilder with the const sizes found on the internet to make it responsive.

Example:

import 'package:flutter/material.dart';

const i13w = 1284.0; // Big screen (Iphone 13 promax width)
const i8w = 750.0; // Small screen (Iphone 8 width)

void main() => runApp(MaterialApp(home: Scaffold(body: MyApp())));

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: LayoutBuilder(builder: (context, constrains) {
        final w = constrains.maxWidth;
        
        renderAsI13() {
          ...
        }
        renderAsI8() {
          ...
        }

        if (w >= i8w) return renderAsI13(); // If screen size bigger than ip8 size, render as bigger way
        return renderAsI8(); // Or else render as diferences way
      }),
    );
  }
}

enter image description here

CodePudding user response:

Hii Gian Wrap will not help you in this situation. You need to use Layout Builder For this problem I have attested a sample code.

import 'package:flutter/material.dart';

class IssueWithWrap extends StatefulWidget {
  const IssueWithWrap({Key? key}) : super(key: key);

  @override
  State<IssueWithWrap> createState() => _IssueWithWrapState();
}

class _IssueWithWrapState extends State<IssueWithWrap> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            LayoutBuilder(
              builder: (context, contraints) {
                print(contraints.biggest.width);
                if (contraints.biggest.width > 550) {
                  return Row(
                    children: [
                      Expanded(
                        child: _ExpandableButton(
                          text: "Book Again",
                        ),
                      ),
                      Expanded(
                        child: _ExpandableButton(
                          text: "Emergency Contact",
                        ),
                      ),
                    ],
                  );
                } else {
                  return Column(
                    children: [
                      _ExpandableButton(
                        width: double.infinity,
                        text: "Book Again",
                      ),
                      _ExpandableButton(
                        width: double.infinity,
                        text: "Emergency Contact",
                      ),
                    ],
                  );
                }
              },
            ),
          ],
        ),
      ),
    );
  }
}

class _ExpandableButton extends StatelessWidget {
  final String text;
  final double? width;

  const _ExpandableButton({Key? key, required this.text, this.width})
      : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: width,
      alignment: Alignment.center,
      decoration: BoxDecoration(
          color: Colors.pink.shade900, borderRadius: BorderRadius.circular(8)),
      child: Text(
        text,
        style: TextStyle(fontSize: 20, color: Colors.white),
      ),
    );
  }
}
  • Related