What does it mean Device Orientation in Flutter
Device Orientation refers to the physical orientation of a device, such as a smartphone or a tablet, in relation to the user. In Flutter, this information can be obtained through the use of a “Sensor” widget that detects the orientation of the device. This is crucial for mobile app developers who aim to create an immersive and interactive experience for their users. The “Device Orientation” feature enables developers to dynamically adjust the app’s layout and behaviour based on the orientation of the device, making it a versatile tool for enhancing user engagement.
However, it is not as simple as just detecting the orientation. Developers must consider the complexities of handling different orientations, as well as the burstiness of changes in orientation. It requires a thorough understanding of the underlying principles and a precise implementation to ensure a seamless experience for the user. The “Device Orientation” feature can be a double-edged sword, as it offers the opportunity for dynamic and engaging experiences, but it also requires careful consideration of its intricacies to avoid affecting the stability and performance of the app.
In conclusion, “Device Orientation” in Flutter is a powerful tool for mobile app developers looking to create engaging and interactive experiences for their users. But it requires a nuanced approach to balancing the complexities of handling orientation changes with the opportunities for enhancing user engagement.
Why do I need Device Screen Orientation?
Device Screen Orientation is a crucial aspect of mobile app development, as it directly affects the user’s experience and interaction with the app. A well-designed app should be able to adapt to different orientations, providing a seamless and intuitive experience for the user, regardless of the device’s physical position. By leveraging the information obtained from the device’s orientation, developers can create dynamic and engaging experiences that are tailored to the user’s needs and preferences.
However, it is not just a matter of convenience. The “Device Screen Orientation” also affects the usability of the app, particularly in terms of accessibility. For example, some users may prefer a portrait orientation for reading, while others may prefer a landscape orientation for watching videos. By enabling the app to dynamically adjust its layout and behaviour based on the orientation of the device, developers can ensure that the app is accessible and usable for a wider range of users.
In addition, the “Device Screen Orientation” also has an impact on the app’s performance. A poorly designed app that does not handle orientation changes properly can lead to slow response times, lag, and even crashes. This can greatly affect the user’s experience and negatively impact the reputation of the app. Hence, it is important for developers to carefully consider the implications of “Device Screen Orientation” and to implement it in a way that balances the complexities of handling orientation changes with the opportunities for enhancing the user experience.
In conclusion, “Device Screen Orientation” is a critical aspect of mobile app development that has a direct impact on the user’s experience and accessibility. A well-designed app that leverages the information obtained from the device’s orientation can provide a dynamic, engaging, and accessible experience for users. However, it requires a nuanced approach to balancing the complexities of handling orientation changes with the opportunities for enhancing user engagement.
Check Device Screen Orientation in Flutter
Flutter Device Orientation with MediaQuery.of
To check the “Device Screen Orientation” in Flutter, you can use the MediaQuery.of
method to retrieve the MediaQueryData
from the nearest ancestor MediaQuery
widget. The MediaQueryData
contains the current screen orientation, which you can retrieve using the orientation
property.
Here’s an example of how to check the “Device Screen Orientation” in Flutter:
@override
Widget build(BuildContext context) {
Orientation orientation = MediaQuery.of(context).orientation;
if (orientation == Orientation.portrait) {
return portraitView();
} else {
return landscapeView();
}
}
In this example, the build
method checks the screen orientation using the MediaQuery.of
method and returns either the portraitView
or landscapeView
widgets, depending on the orientation.
Here’s an example of how you could define the portraitView
and landscapeView
functions that work with the MediaQuery.of code shown above:
Widget portraitView() {
return Scaffold(
body: Container(
color: Colors.red,
child: Center(
child: Text('Portrait View'),
),
),
);
}
Widget landscapeView() {
return Scaffold(
body: Container(
color: Colors.green,
child: Center(
child: Text('Landscape View'),
),
),
);
}
In this example, the portraitView
function returns the Scaffold
with a red Container
with a text that says “Portrait View”. The landscapeView
function returns the Scaffold
with a green Container
with a text that says “Landscape View”.
Flutter Device Orientation with OrientationBuilder
You can also check the “Device Screen Orientation” in Flutter using the OrientationBuilder
widget.
The OrientationBuilder
is a widget that rebuilds whenever the screen orientation changes. It takes a builder function as an argument, which is called with the current screen orientation. The builder function returns a widget, which is then displayed on the screen.
Here’s an example of how to use the OrientationBuilder
widget to check the “Device Screen Orientation” in Flutter:
@override
Widget build(BuildContext context) {
return OrientationBuilder(
builder: (context, orientation) {
if (orientation == Orientation.portrait) {
return portraitView();
} else {
return landscapeView();
}
},
);
}
In this example, the HomePage
widget uses the OrientationBuilder
widget to return either the portraitView
or landscapeView
widgets, depending on the orientation. The OrientationBuilder
widget automatically listens to changes in the screen orientation and calls the builder function whenever the orientation changes.
Using the OrientationBuilder
widget is a convenient way to check the “Device Screen Orientation” in Flutter, as it reduces the amount of boilerplate code you need to write and allows you to focus on implementing the layout and behaviour of your app for each orientation.
Widget portraitView() {
return Scaffold(
body: Container(
color: Colors.red,
child: Center(
child: Text('Portrait View'),
),
),
);
}
Widget landscapeView() {
return Scaffold(
body: Container(
color: Colors.green,
child: Center(
child: Text('Landscape View'),
),
),
);
}
Portrait Device Orientation in Flutter
Portrait device orientation refers to the way a device is held vertically, with its height greater than its width. In this orientation, the screen is taller than it is wide and the user views content in a portrait or vertical format. This is the most common orientation used on mobile devices and handhelds, such as smartphones and tablets, for reading, browsing the web, or using social media apps.
When a device is held in portrait orientation, it’s easier for users to hold the device in one hand and interact with it using their thumb. This orientation also makes it easier for users to see the entire screen without having to scroll, which can be convenient for tasks such as reading articles or using apps that display vertical lists.
Flutter DeviceOrientation.portraitUp
DeviceOrientation.portraitUp
is a value within the DeviceOrientation
enum class in Flutter, which specifies the orientation of a device where the top of the device is facing upwards in a portrait mode.
The DeviceOrientation
class is used to define and set the orientation of a device for a Flutter application, with other possible values being landscapeLeft
, landscapeRight
, and portraitDown
. Utilizing DeviceOrientation.portraitUp
in combination with the SystemChrome.setPreferredOrientations
method allows developers to set the preferred orientation of their Flutter app to portrait mode.
Flutter DeviceOrientation.portraitDown
DeviceOrientation.portraitDown
is a value in the DeviceOrientation
enum class in Flutter that indicates a device orientation where the top of the device is facing downwards in portrait mode. This value is one of several that the DeviceOrientation
class provides for defining and setting a device’s orientation in a Flutter application, including landscapeLeft
, landscapeRight
, and portraitUp
.
By utilizing DeviceOrientation.portraitDown
and the SystemChrome.setPreferredOrientations
method, developers can specify the desired orientation of their Flutter app to be portrait mode with the top of the device facing downwards, as opposed to the previously described portraitUp
.
Set Portrait Device Orientation in Flutter
To set the portrait device orientation in Flutter, you can use the SystemChrome.setPreferredOrientations
method. This method is typically called inside the main
method and before the runApp
method, as it sets the preferred orientation for the entire app. The SystemChrome.setPreferredOrientations
method takes a single argument, which is a list of DeviceOrientation
values, and in our case, it will be [DeviceOrientation.portraitUp]
.
Here’s an example of how to set the portrait device orientation in Flutter:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
//SystemChrome.setPreferredOrientations([DeviceOrientation.portraitDown]);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Portrait Device Orientation"),
),
);
}
}
Note that the SystemChrome.setPreferredOrientations
method should be called before the runApp
method, as the method sets the preferred orientation for the entire app.
You can also find the code can look like this:
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]).then((value) => runApp(MyApp()));
Landscape Device Orientation in Flutter
Landscape device orientation refers to the way a device is held horizontally, with its width greater than its height. In this orientation, the screen is wider than it is tall and the user views content in a landscape or horizontal format. This orientation is commonly used on larger devices such as laptops, desktop computers, and televisions.
When a device is held in landscape orientation, it provides a wider screen for real estate, making it easier to see multiple columns of content or to view widescreen videos and images. This orientation is often used for tasks that benefit from a larger display, such as watching movies, playing games, or using productivity apps like spreadsheets or presentations.
Flutter DeviceOrientation.landscapeLeft
DeviceOrientation.landscapeLeft
is a value within the DeviceOrientation
enum class in Flutter that defines a device’s orientation as landscape mode with the device rotated to the left. This value is one of several available to developers for setting the preferred orientation of their Flutter app, such as portraitUp
, portraitDown
, and landscapeRight
.
By utilizing DeviceOrientation.landscapeLeft
in conjunction with the SystemChrome.setPreferredOrientations
method, developers can specify that their app should be in landscape mode with the device rotated to the left. This allows them to take advantage of the wider screen real estate that landscape mode provides while tailoring the app’s experience to the desired orientation.
Flutter DeviceOrientation.landscapeRight
DeviceOrientation.landscapeRight
, similar to DeviceOrientation.landscapeLeft
, is a value within Flutter DeviceOrientation
enum class, which represents the device’s orientation in landscape mode. However, this value distinguishes itself by specifying that the device is rotated to the right, rather than to the left.
When utilized in conjunction with the SystemChrome.setPreferredOrientations
method, developers can set their app’s preferred orientation as landscapeRight
. This grants the app the benefits of landscape mode’s larger screen area, all while customizing the app’s experience to the desired orientation.
The Flutter's DeviceOrientation
enum class also includes values such as portraitUp
, portraitDown
, to allow developers to create dynamic experiences that respond to the device’s orientation.
Set Landscape Device Orientation in Flutter
To set the landscape device orientation in Flutter, you can do exactly the same as in the example above where we set the device orientation to portrait mode.
Here’s an example of how to set the landscape device orientation in Flutter:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeLeft]);
//SystemChrome.setPreferredOrientations([DeviceOrientation.landscapeRight]);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Landscape Device Orientation"),
),
);
}
}
Set Portrait Device Orientation for Specific Screen in Flutter
In this example, we will use the following code to set the orientation of the current screen to portrait only.
@override
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
}
The above code is used to set a device orientation to portrait mode for a specific screen in Flutter. This is done by overriding the initState() method and adding the SystemChrome.setPreferredOrientations() method.
The SystemChrome.setPreferredOrientations() method takes a list of device orientations as an argument and sets the orientation of the device to the list provided. In this case, the orientation is set to portrait up and portrait down. This means that the device will be locked in either portrait up or portrait down orientation, depending on which orientation the user has chosen.
The code is useful for ensuring that a specific screen in an application is always displayed in portrait mode. For example, if an application has a login screen, this code can be used to ensure that the login screen is always displayed in portrait mode, regardless of how the user has rotated their device. This ensures that the application always looks professional and consistent.
Set Landscape Device Orientation for Specific Screen in Flutter
To set the device screen orientation to landscape, you need to override the initState() method and call the setPreferredOrientations() method. The code below shows an example of how to accomplish this.
@override
void initState() {
super.initState();
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
]);
}
In the above code, the setPreferredOrientations()
method is called with two parameters: DeviceOrientation.landscapeRight
and DeviceOrientation.landscapeLeft
. This tells the system to set the preferred orientation of the device to either landscape right or landscape left when this particular screen is displayed.
The setPreferredOrientations()
method is called in the initState()
method so that it will be executed each time the screen is shown. This ensures that the preferred orientation of the device will always be set to landscape right or landscape left whenever the screen is displayed.
How to reset Device Orientation in Specific Screen in Flutter
@override
void dispose() {
SystemChrome.setPreferredOrientations([
DeviceOrientation.landscapeRight,
DeviceOrientation.landscapeLeft,
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
super.dispose();
}
The above code is a simple way to reset the device orientation in a specific screen in a Flutter application. It is achieved by overriding the dispose()
function of the State class and calling the SystemChrome.setPreferredOrientations()
method.
The setPreferredOrientations()
method takes an array argument which consists of the device orientations that should be set. In this example, we are setting the device orientation to landscapeRigh
t, landscapeLeft
, portraitUp
, and portraitDown
.
Once the device orientation is set, the dispose() method of the State class is called with the super keyword to ensure the parent class’s dispose()
method is called. This resets the device orientation and allows the application to run in the desired orientation for the specific screen.
Changing Device Orientation Programmatically with Button in Flutter
You can also change the device screen orientation with the click of a button. You can call SystemChrome.setPreferredOrientations method and change the orientation as you need.
Here is a code example that demonstrates the above:
bool _ScreenRotation = false;
ElevatedButton(
onPressed: () {
_ScreenRotation == false
?
SystemChrome.setPreferredOrientations(
[DeviceOrientation.landscapeLeft])
:
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp]);
setState(() {
_ScreenRotation = !_ScreenRotation;
});
},
child: const Text(
'Rotate the screen',
style: TextStyle(fontSize: 24),
),
),
This code snippet is used to change the device orientation programmatically in Flutter. It uses an ElevatedButton
to call the function that can change the device orientation. The boolean variable _ScreenRotation
is used to keep track of the current orientation and toggle it when the button is pressed.
When the button is pressed, the system checks the value of _ScreenRotation
and then uses the SystemChrome.setPreferredOrientations()
method to set the preferred orientation. If _ScreenRotation
is false
, the orientation is set to landscapeLeft
, and if it is to true
, the orientation is set to portraitUp
.
Finally, the value of _ScreenRotation
is toggled, so that the next time the button is pressed, the orientation will be changed again.
Here is the full code:
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _ScreenRotation = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
_ScreenRotation == false
?
SystemChrome.setPreferredOrientations(
[DeviceOrientation.landscapeLeft])
:
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp]);
setState(() {
_ScreenRotation = !_ScreenRotation;
});
},
child: const Text(
'Rotate the screen',
style: TextStyle(fontSize: 24),
),
),
],
),
),
);
}
}
How to manage Device Orientation with OrientationBuilder
The OrientationBuilder widget in Flutter provides a comprehensive solution for managing device orientation within your app. This widget listens attentively to the changes in the device orientation, and with its dynamic capabilities, it rebuilds the widget tree according to the new orientation, ensuring that the app’s layout is always optimized for the user’s experience.
By including this widget in your code, you can offer a seamless and efficient experience to your users, adapting to their preferred orientation with ease. With its powerful features, the OrientationBuilder opens up a world of opportunities for tailoring the app’s layout and functionality, providing a more personalized and engaging experience.
Here’s a snippet of code to showcase the OrientationBuilder in action:
OrientationBuilder(
builder: (context, orientation) {
return orientation == Orientation.portrait
? Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Container(
color: Colors.red,
),
),
Expanded(
child: Container(
color: Colors.blue,
),
),
],
)
: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Container(
color: Colors.red,
),
),
Expanded(
child: Container(
color: Colors.blue,
),
),
],
);
},
)
The OrientationBuilder
widget takes a builder
function as a parameter that returns a widget based on the device’s orientation. In this example, it checks the value of orientation
and returns either a Column
widget or a Row
widget depending on the orientation. The mainAxisAlignment
property of the Column
and Row
widgets is set to MainAxisAlignment.spaceBetween
, which aligns the children widgets evenly along the main axis.
The Expanded
widget is used to make the Container
widgets fill the available space along the cross-axis. The Container
widgets are given a background colour of either red or blue, allowing us to visually distinguish them.
The full code is here:
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
// WidgetsFlutterBinding.ensureInitialized();
//
// SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
// SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown,]);
// SystemChrome.setPreferredOrientations([
// DeviceOrientation.landscapeLeft,
// DeviceOrientation.landscapeRight,
// ]).then((value) => runApp(MyApp()));
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>{
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: OrientationBuilder(
builder: (context, orientation) {
return orientation == Orientation.portrait
? Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Container(
color: Colors.red,
),
),
Expanded(
child: Container(
color: Colors.blue,
),
),
],
)
: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Expanded(
child: Container(
color: Colors.red,
),
),
Expanded(
child: Container(
color: Colors.blue,
),
),
],
);
},
),
);
}
}
How to manage Device Orientation with MediaQuery.of
The MediaQuery.of method in Flutter provides a highly effective solution for managing device orientation within your app. This method leverages the MediaQuery data to determine the device’s orientation, and it can be used to create layouts that respond dynamically to changes in orientation.
With its versatile capabilities, the MediaQuery.of method makes it simple to tailor the app’s layout to fit the user’s preferred orientation, whether it be portrait or landscape. This provides a more personalized and engaging experience for your users, helping to ensure that your app is always optimized for their needs.
Here’s a snippet of code to showcase the MediaQuery.of method in action:
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) {
if (MediaQuery.of(context).orientation == Orientation.portrait) {
return Column(
children: [
Container(
height: constraints.maxHeight / 2,
width: double.infinity,
color: Colors.red,
),
Container(
height: constraints.maxHeight / 2,
width: double.infinity,
color: Colors.blue,
),
],
);
} else {
return Row(
children: [
Container(
height: double.infinity,
width: constraints.maxWidth / 2,
color: Colors.red,
),
Container(
height: double.infinity,
width: constraints.maxWidth / 2,
color: Colors.blue,
),
],
);
}
},
),
);
This code is a Flutter widget that displays two coloured Container widgets on the screen, one in red and one in blue. The layout of these containers depends on the device’s orientation, which is determined by the MediaQuery.of(context).orientation
expression. If the device is in portrait orientation, the Containers are arranged vertically in a column. If the device is in landscape orientation, the Containers are arranged horizontally in a row.
The height and width of each Container widget are set to half the screen size, which is determined by the constraints
argument passed to the LayoutBuilder
widget’s builder
function. The constraints.maxHeight
value represents the maximum height of the available space, and the constraints.maxWidth
value represents the maximum width of the available space. By setting the height of each Container to constraints.maxHeight / 2
and the width of each Container to constraints.maxWidth / 2
, we ensure that each Container takes up half the screen.
Here is the full code:
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>{
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('flutterassets.com'),
),
body: LayoutBuilder(
builder: (context, constraints) {
if (MediaQuery.of(context).orientation == Orientation.portrait) {
return Column(
children: [
Container(
height: constraints.maxHeight / 2,
width: double.infinity,
color: Colors.red,
),
Container(
height: constraints.maxHeight / 2,
width: double.infinity,
color: Colors.blue,
),
],
);
} else {
return Row(
children: [
Container(
height: double.infinity,
width: constraints.maxWidth / 2,
color: Colors.red,
),
Container(
height: double.infinity,
width: constraints.maxWidth / 2,
color: Colors.blue,
),
],
);
}
},
),
);
}
}