Developing For Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) - by Deven Joshi - Flutter Community - Medium

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 26

3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter

Flutter Community | Med…

Published in Flutter Community

Deven Joshi Follow

Oct 24, 2018 · 10 min read · Listen

Save

Developing for Multiple Screen Sizes and


Orientations in Flutter (Fragments in Flutter)
Making Adaptive Screens in Google’s Flutter Mobile SDK

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 1/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

Mobile applications need to support a wide range of device sizes, pixel densities and
orientations. Apps need to be able to scale well, handle orientation changes and persist
data through all these. Flutter gives you the capability to choose the way to tackle these
challenges instead of only giving one particular solution.

The Android solution for tackling larger screens


In Android, we tackle larger screens like tablets with alternate layout files which we
can define for a minimum width and landscape/portrait orientation.

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 2/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

Meaning we have to define one layout file for phones, one for tablets and then both
orientations for each device type. These layouts are then instantiated according to
whichever device is running it. We then check for which layout is active(mobile/tablet)
and initialise accordingly.

For most applications, a master-detail flow is used for handling larger screen sizes,
which uses Fragments. We’ll go into what master-detail flow is in a while.

Fragments in Android are essentially reusable components which can be used in a


screen. Fragments have their own layouts and Java/Kotlin classes to control the data
and for the lifecycle of the Fragment. This is a rather large undertaking and takes a lot
of code to get working.

Let us first look at handling orientation and then handling screen sizes for Flutter.

Working with orientation in Flutter


When we work with orientation, we want to use the full width of the screen and display
the maximum amount of information possible.
https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 3/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

The example below creates a rudimentary profile page in both orientations and builds
the layout differently depending on the orientation to maximise the use of the width of
the screen. The complete source code will be hosted on GitHub (Link given at the end
of this article).

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 4/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 5/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

Here we have a simple screen which has different layouts for portrait as well as
landscape. Let’s try to understand how we actually switch layouts in Flutter by creating
the example above.

How do we go about this?

In concept, we work very similarly to the Android way of doing things. We have two
layouts (not layout files, as Flutter doesn't have those), one for portrait and one for
landscape orientation. When the device changes orientation we rebuild our layout.

How do we detect orientation changes?


To start out, we use a widget called OrientationBuilder. OrientationBuilder is a widget
which builds a layout or part of a layout on an orientation change.

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: OrientationBuilder(
builder: (context, orientation) {
return orientation == Orientation.portrait
? _buildVerticalLayout()
: _buildHorizontalLayout();
},
),
);
}

The OrientationBuilder has a builder function to build our layout. The builder function
is called when the orientation changes. The possible values being Orientation.portrait
or Orientation.landscape.

In this example, we check if the screen is in portrait mode and construct a vertical
layout if that is the case, else we construct a horizontal layout for the screen.

_buildVerticalLayout() and _buildHorizontalLayout() are methods I’ve written to


create the respective layouts.

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 6/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

We can also check the orientation at any point in the code (inside or outside the
OrientationBuilder) using

MediaQuery.of(context).orientation

Note: For that time when we’re lazy and/or only portrait will do, use

SystemChrome.setPreferredOrientations(DeviceOrientation.portraitUp);

Creating layouts for larger screens in Flutter


When we deal with larger screen sizes, we want our screens to adapt to use the
available space on the screen. The most straight-forward way to do this is simply
creating two different layouts or even screens for tablets and phones. (Here, “layout”
means the visual part of the screen. “Screen” refers to the layout and the all the
backend code connected to it.) However this involves a lot of unnecessary code and the
code needs to be repeated.

So what do we do to solve this problem?

First, let’s take a look at the most common use case of it.

Let’s go back to the “Master-Detail Flow” we were going to talk about. When it comes to
apps, you will see a common pattern where you have a Master list of items and when
you click on a list item, you get redirected to a different Detail screen. Take the
example of Gmail, where we have a list of emails and when we click on one, a detail
view opens with the content of the mail.

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 7/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

Let’s take make an example app for this flow.

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 8/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 9/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

Master-Detail Flow in mobile portrait mode

This app simply holds a list of numbers and displays a number prominently when
tapped on. We have a master list of numbers and a detail view that displays a number
when clicked. Just like the emails.

If we used the same layout in tablets, it would be a rather large waste of space. So what
can we do to solve it? We can have both the master list and detail view on the same
screen as we have the available screen space.

Master-Detail Flow in tablet landscape mode

So what can we do to reduce the work of writing two separate screens?

Let’s see how Android tackles this. Android creates reusable components called
Fragments out of the master list and the detail view. A Fragment can be defined

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 10/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

separately from the screen and just added into the screen without repeating the code
twice.

Open in app Sign up Sign In

Search Medium
So Fragment A is the master list fragment and B is the detail fragment. In mobiles or
smaller width layouts, a click on a list item would navigate to a separate page whereas
in tablets it would remain on the same page and change the detail fragment. We can
also do a tablet-like interface when a phone is rotated to landscape.

This is where the power of Flutter comes in.

Every widget in Flutter is by nature, reusable.

Every widget in Flutter is like a Fragment.

All we need to do is define two widgets. One for the master list, one for the detail view.
These are, in effect, fragments. We simply check if the device has enough width to
handle both the list and detail part. If it does, we use both widgets. If the device does
not have enough width to support both, we only show the list and navigate to a
separate screen to show the detail content.

We first need to check the device’s width to see if we can use the larger layout instead
of the smaller one. To get the width, we use

MediaQuery.of(context).size.width

The Size gives us the height and width of the device in dps.
https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 11/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

Let’s set the minimum width to 600 dp for switching to the second layout.

Summing up:
1. We create two widgets, one containing the master list and one containing the detail
view.

2. We create two screens. On the first screen, we check if the device has enough
width to handle both widgets.

3. If there is enough width, we add both widgets on one page. If there is not, we
navigate to a second page when a list item is tapped which only has a detail view.
6.4K 17

Let’s code it
Let’s code the demo that I’ve included at the top of this section where we have a list of
numbers and the detail view displays that number. First we make two widgets.

The List Widget (List Fragment)

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 12/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 13/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

typedef Null ItemSelectedCallback(int value);

class ListWidget extends StatefulWidget {


final int count;
final ItemSelectedCallback onItemSelected;

ListWidget(
this.count,
this.onItemSelected,
);

@override
_ListWidgetState createState() => _ListWidgetState();
}

class _ListWidgetState extends State<ListWidget> {


@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: widget.count,
itemBuilder: (context, position) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Card(
child: InkWell(
onTap: () {
widget.onItemSelected(position);
},
child: Row(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: Text(position.toString(), style:
TextStyle(fontSize: 22.0),),
),
],
),
),
),
);
},
);
}
}

In the list, we take how many items we want to display as well as a callback when an
item is clicked. This callback is important as it decides whether to simply change the
detail view on a larger screen or navigate to a different page on a smaller screen.
https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 14/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

We simply display cards for each index and surround it with an InkWell to respond to
taps.

The Detail Widget (Detail Fragment)

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 15/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 16/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

class DetailWidget extends StatefulWidget {

final int data;

DetailWidget(this.data);

@override
_DetailWidgetState createState() => _DetailWidgetState();
}

class _DetailWidgetState extends State<DetailWidget> {


@override
Widget build(BuildContext context) {
return Container(
color: Colors.blue,
child: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(widget.data.toString(), style: TextStyle(fontSize:
36.0, color: Colors.white),),
],
),
),
);
}
}

The Detail Widget simply takes a number and displays it prominently.

Notice that these are not screens. These are simply widgets we are going to use on the
screens.

The Main Screen

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 17/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

class MasterDetailPage extends StatefulWidget {


@override
_MasterDetailPageState createState() => _MasterDetailPageState();
}

class _MasterDetailPageState extends State<MasterDetailPage> {


var selectedValue = 0;
var isLargeScreen = false;

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: OrientationBuilder(builder: (context, orientation) {

if (MediaQuery.of(context).size.width > 600) {


isLargeScreen = true;
} else {
isLargeScreen = false;
}

return Row(children: <Widget>[


Expanded(

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 18/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

child: ListWidget(10, (value) {


if (isLargeScreen) {
selectedValue = value;
setState(() {});
} else {
Navigator.push(context, MaterialPageRoute(
builder: (context) {
return DetailPage(value);
},
));
}
}),
),
isLargeScreen ? Expanded(child: DetailWidget(selectedValue))
: Container(),
]);
}),
);
}
}

This is the main page of the app. We have two variables: selectedValue for storing the
selected list item, and isLargeScreen is a simple boolean which stores if the screen is
large enough to display both the list and detail widgets.

We also have an OrientationBuilder around it, so that if a mobile phone is rotated to


landscape mode and it has enough width to display both elements, then it will rebuild
in that way.

We first check if the width is large enough to display our layout using

if (MediaQuery.of(context).size.width > 600) {


isLargeScreen = true;
} else {
isLargeScreen = false;
}

The main part of the code is:

isLargeScreen ? Expanded(child: DetailWidget(selectedValue)) :

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 19/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

Container(),

If the screen is large, we add a detail widget, and if it is not, we return an empty
container. We use the Expanded widgets around it to fill the screen or divide the screen
into proportions in case of a larger screen. So Expanded allows each widget to fill half
of the screen or even a certain percentage by setting the Flex property.

The second important part is:

if (isLargeScreen) {
selectedValue = value;
setState(() {});
} else {
Navigator.push(context, MaterialPageRoute(
builder: (context) {
return DetailPage(value);
},
));
}

Meaning, if the larger layout is used, we don’t need to go to a different screen as the
detail widget is on the page itself. If the screen is smaller, we need to navigate to a
different page as only the list is displayed on the current screen.

And finally,

The Detail Page (For smaller screens)

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 20/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 21/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

class DetailPage extends StatefulWidget {

final int data;

DetailPage(this.data);

@override
_DetailPageState createState() => _DetailPageState();
}

class _DetailPageState extends State<DetailPage> {


@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: DetailWidget(widget.data),
);
}
}

It only holds one detail widget on the page, and is used for displaying the data on
smaller screens.

Now we have a functioning app that adapts to screens of different sizes and their
orientation.

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 22/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

Some more important things


1. If you want to simply have different layouts and not have any Fragment-like
layouts, you can just simply write inside the build method

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 23/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

if (MediaQuery.of(context).size.width > 600) {


isLargeScreen = true;
} else {
isLargeScreen = false;
}
return isLargeScreen? _buildTabletLayout() : _buildMobileLayout();

And write two methods to build your layouts.

2. If you want to have a design for tablets only, instead of checking for width from
MediaQuery, get the size and use it to get actual width instead of width in that specific
orientation. When we used the width from MediaQuery directly, it will get the get the
width in that orientation only. So in landscape mode, the length of the phone is
considered width.

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


double width = size.width > size.height ? size.height : size.width;

if(width > 600) {


// Do something for tablets here
} else {
// Do something for phones
}

Github Link for the samples in this article:

https://github.com/deven98/FlutterAdaptiveLayouts

That’s it for this article! I hope you enjoyed it and leave


a few claps if you did. Follow me for more Flutter
articles and comment for any feedback you might
have about this article.
Some of my other articles

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 24/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

Flutter Challenge: YouTube (Picture-In-Picture)


Flutter Challenges will attempt to recreate a particular app UI or design
in Flutter.
proandroiddev.com

Animated Widgets in Flutter


Simplifying animations in Flutter with Implicitly Animated Widgets
medium.com

Answering Questions on Flutter App Development


After interacting with a lot of students and developers personally and
through my talks and workshops, I realised a lot…
medium.com

Find more content in the Flutter Community and follow us for notifications on Twitter.

Flutter Community (@FlutterComm) | Twitter


The latest Tweets from Flutter Community (@FlutterComm). Follow to
get notifications of new articles and packages from…
twitter.com

Android App Development Flutter Programming Software Engineering

Technology

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 25/26
3/18/23, 1:37 PM Developing for Multiple Screen Sizes and Orientations in Flutter (Fragments in Flutter) | by Deven Joshi | Flutter Community | Med…

About Help Terms Privacy

Get the Medium app

https://medium.com/flutter-community/developing-for-multiple-screen-sizes-and-orientations-in-flutter-fragments-in-flutter-a4c51b849434 26/26

You might also like