Sizing elements to percentage of screen width/height

FlutterDartFlutter LayoutScreen Size

Flutter Problem Overview


Is there a simple (non-LayoutBuilder) way to size an element relative to screen size (width/height)? For example: how do I set the width of a CardView to be 65% of the screen width.

It can't be done inside the build method (obviously) so it would have to be deferred until post build. Is there a preferred place to put logic like this?

Flutter Solutions


Solution 1 - Flutter

This is a supplemental answer showing the implementation of a couple of the solutions mentioned.

FractionallySizedBox

If you have a single widget you can use a FractionallySizedBox widget to specify a percentage of the available space to fill. Here the green Container is set to fill 70% of the available width and 30% of the available height.

https://i.stack.imgur.com/LRSc5.png" width="300" alt="FractionallySizedBox">

Widget myWidget() {
  return FractionallySizedBox(
    widthFactor: 0.7,
    heightFactor: 0.3,
    child: Container(
      color: Colors.green,
    ),
  );
}
Expanded

The Expanded widget allows a widget to fill the available space, horizontally if it is in a row, or vertically if it is in a column. You can use the flex property with multiple widgets to give them weights. Here the green Container takes 70% of the width and the yellow Container takes 30% of the width.

https://i.stack.imgur.com/cY4AS.png" width="300" alt="Expanded">

If you want to do it vertically, then just replace Row with Column.

Widget myWidget() {
  return Row(
    children: <Widget>[
      Expanded(
        flex: 7,
        child: Container(
          color: Colors.green,
        ),
      ),
      Expanded(
        flex: 3,
        child: Container(
          color: Colors.yellow,
        ),
      ),
    ],
  );
}
Supplemental code

Here is the main.dart code for your reference.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("FractionallySizedBox"),
        ),
        body: myWidget(),
      ),
    );
  }
}

// replace with example code above
Widget myWidget() {
  return ...
}

Solution 2 - Flutter

FractionallySizedBox may also be useful. You can also read the screen width directly out of MediaQuery.of(context).size and create a sized box based on that

MediaQuery.of(context).size.width * 0.65

if you really want to size as a fraction of the screen regardless of what the layout is.

Solution 3 - Flutter

This might be a little more clear:

double width = MediaQuery.of(context).size.width;

double yourWidth = width * 0.65;

Hope this solved your problem.

Solution 4 - Flutter

There are several possibilities:

1- The first one is the use of the MediaQuery :

Code :

MediaQuery.of(context).size.width //to get the width of screen
MediaQuery.of(context).size.height //to get height of screen

Example of use :

Container(
        color: Colors.yellow,
        height: MediaQuery.of(context).size.height * 0.65,
        width: MediaQuery.of(context).size.width,
      )

Output :

enter image description here

2- The use of FractionallySizedBox

Creates a widget that sizes its child to a fraction of the total available space.

Example :

FractionallySizedBox(
           widthFactor: 0.65, // between 0 and 1 
           heightFactor: 1.0,
           child:Container(color: Colors.red
           ,),
         )

Output :

enter image description here

3- The use of other widgets such as Expanded , Flexible and AspectRatio and more .

Solution 5 - Flutter

You could build a Column/Row with Flexible or Expanded children that have flex values that add up to the percentages you want.

You may also find the AspectRatio widget useful.

Solution 6 - Flutter

There is many way to do this.

1. Using MediaQuery : Its return fullscreen of your device including appbar,toolbar

 Container(
        width: MediaQuery.of(context).size.width * 0.50,
        height: MediaQuery.of(context).size.height*0.50, 
        color: Colors.blueAccent[400],
 )

enter image description here


2. Using Expanded : You can set width/height in ratio

 Container(
        height: MediaQuery.of(context).size.height * 0.50,
        child: Row(
          children: <Widget>[
            Expanded(
              flex: 70,
              child: Container(
                color: Colors.lightBlue[400],
              ),
            ),
            Expanded(
              flex: 30,
              child: Container(
                color: Colors.deepPurple[800],
              ),
            )
          ],
        ),
    )

enter image description here



3. Others Like Flexible and AspectRatio and FractionallySizedBox

Solution 7 - Flutter

First get the size of screen.

Size size = MediaQuery.of(context).size;

After this you can get width and multiply it with 0.5 to get 50% of screen width.

double width50 = size.width * 0.5;

But problem generally comes in height, by default when we use

double screenHeight = size.height;

The height we get is global height which includes StatusBar + notch + AppBar height. So, in order to get the left height of the device, we need to subtract padding height (StatusBar + notch) and AppBar height from total height. Here is how we do it.

double abovePadding = MediaQuery.of(context).padding.top;
double appBarHeight = appBar.preferredSize.height;
double leftHeight = screenHeight - abovePadding - appBarHeight;

Now we can use following to get 50% of our screen in height.

double height50 = leftHeight * 0.5

Solution 8 - Flutter

MediaQuery.of(context).size.width

Solution 9 - Flutter

you can use MediaQuery with the current context of your widget and get width or height like this

double width = MediaQuery.of(context).size.width
double height = MediaQuery.of(context).size.height

after that, you can multiply it with the percentage you want

Solution 10 - Flutter

Use the LayoutBuilder Widget that will give you constraints that you can use to obtain the height that excludes the AppBar and the padding. Then use a SizedBox and provide the width and height using the constraints from the LayoutBuilder

return LayoutBuilder(builder: (context2, constraints) {
  return Column(
    children: <Widget>[
      SizedBox(
        width: constraints.maxWidth,
        height: constraints.maxHeight,
        ...

Solution 11 - Flutter

if you are using GridView you can use something like Ian Hickson's solution.

crossAxisCount: MediaQuery.of(context).size.width <= 400.0 ? 3 : MediaQuery.of(context).size.width >= 1000.0 ? 5 : 4

Solution 12 - Flutter

Code :

MediaQuery.of(context).size.width //to get the width of screen
MediaQuery.of(context).size.height //to get height of screen

Solution 13 - Flutter

You can use the Align widget. The heightFactor and widthFactor parameters are multiplied by the size of the child widget. Here is an example that will make a widget with a fixed height in% ratio

         Align(
            alignment: Alignment.topCenter,
            heightFactor: 0.63,
            widthFactor: ,
            child: Container(
              width: double.infinity,
            ),

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLukeView Question on Stackoverflow
Solution 1 - FlutterSuragchView Answer on Stackoverflow
Solution 2 - FlutterIan HicksonView Answer on Stackoverflow
Solution 3 - FlutterKeshav Aditya R.PView Answer on Stackoverflow
Solution 4 - FlutterKab AgoudaView Answer on Stackoverflow
Solution 5 - FlutterCollin JacksonView Answer on Stackoverflow
Solution 6 - FlutterSanjayrajsinhView Answer on Stackoverflow
Solution 7 - FlutterCopsOnRoadView Answer on Stackoverflow
Solution 8 - FlutterNitin MehtaView Answer on Stackoverflow
Solution 9 - Flutterparth jansariView Answer on Stackoverflow
Solution 10 - FlutterNicolasView Answer on Stackoverflow
Solution 11 - FlutterRody DavisView Answer on Stackoverflow
Solution 12 - Flutteruser11644496View Answer on Stackoverflow
Solution 13 - FlutterBio BoJlkView Answer on Stackoverflow