Search code examples
flutterdartflutter-layout

How to set the size of an ElevatedButton in Flutter?


I can't set the size of an Elevated button in Flutter. I have tried enclosing it in a sized box but my code doesn't work. I'm not sure where the size is coming from but I can't change it.

Here's my code:

  Widget build(BuildContext context) {
    return SizedBox(
      width: 60,
      height: 60,
      child: Padding(
        padding: const EdgeInsets.only(top: 20, bottom: 20),
        child: ElevatedButton(
          onPressed: () {},
          style: ElevatedButton.styleFrom(
            elevation: 10,
            backgroundColor: Colors.deepOrange,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(30), // <-- Radius
            ),
            padding: EdgeInsets.all(4),
          ),
          child: Text(
            table.tableNumber,
            style: TextStyle(
              color: Colors.white,
              fontWeight: FontWeight.normal,
              fontSize: 20,
            ),
            overflow: TextOverflow.ellipsis,
            maxLines: 1,
            textAlign: TextAlign.left,
          ),
        ),
      ),
    );
  }

From my scaffold:

class TablesShopView extends StatefulWidget {
  const TablesShopView({super.key});

  @override
  State<StatefulWidget> createState() => TablesShopViewState();
}

class TablesShopViewState extends State<TablesShopView> {
  @override
  void initState() {
    WidgetsBinding.instance.addPostFrameCallback((_) => showSnackBar(context));
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Theme.of(context).backgroundColor,
      resizeToAvoidBottomInset: false,
      body: Container(
        decoration: BoxDecoration(
          gradient: LinearGradient(
              colors: [appBackgroundColorStart, appBackgroundColorEnd],
              begin: Alignment.topLeft,
              end: Alignment.bottomRight),
        ),
        child: Padding(
          padding: const EdgeInsets.all(20.0),
          child: SingleChildScrollView(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                const SizedBox(height: 12),
                const TablesShop(),
              ],
            ),
          ),
        ),
      ),
    );
  }
}


class TablesShop extends StatelessWidget {
  const TablesShop({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BaseWidget<TablesModel>(
      model: TablesModel(api: Provider.of(context, listen: false)),
      onModelReady: (model) => model.fetchTables(),
      child: const SizedBox.shrink(),
      builder: (context, model, child) => model.busy
          ? const Center(
              child: CircularProgressIndicator(),
            )
          : GridView.builder(
              scrollDirection: Axis.vertical,
              shrinkWrap: true,
              physics: const NeverScrollableScrollPhysics(),
              padding: const EdgeInsets.all(10.0),
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisSpacing: 10.0,
                mainAxisSpacing: 10.0,
                crossAxisCount: 5,
                // childAspectRatio: MediaQuery.of(context).size.width /
                //     (MediaQuery.of(context).size.width),
              ),
              itemCount: model.tables.length,
              itemBuilder: (context, index) => TableShopListItem(
                table: model.tables[index],
              ),
            ),
    );
  }
}

edit: Because Gridview always maintains its aspect ratio as mentioned in the accepted answer below, the solution for me was to remove the sized box and elevated button dimensions completely and increase the circle radius to 300. With a grid crossAxisCount of 5, this maintained a perfect circle at any screen size. While the buttom size will change with the screen size that still works for me.


Solution

  • Use Wrap widget for your case. GridItem will maintain aspect ratio for its children. As for the shape, I think you are trying get shape: CircleBorder(), /shape: StadiumBorder(),

     return Wrap(
          children: [
            for (int i = 0; i < 33; i++)
              TableShopListItem(
               ....
              ),
          ],
        );
    

    If the top widget is not handling scroll event, wrap the Wrap widget scrollable widget.

    You can check more about constraints