How to Get Screen Dimensions in Flutter: Width, Height, and More
•8 min read
Understanding and working with screen dimensions is crucial for creating responsive Flutter applications. This guide covers everything you need to know about getting and using screen dimensions effectively.
Basic Screen Dimensions
1. Getting Screen Width and Height
The most basic way to get screen dimensions is using MediaQuery
:
class ScreenDimensionsDemo extends StatelessWidget { @override Widget build(BuildContext context) { // Get screen dimensions double screenWidth = MediaQuery.of(context).size.width; double screenHeight = MediaQuery.of(context).size.height; return Scaffold( appBar: AppBar(title: Text('Screen Dimensions')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Screen Width: $screenWidth'), Text('Screen Height: $screenHeight'), ], ), ), ); } }
2. Safe Area and Padding
Get dimensions considering system UI elements:
class SafeAreaDimensionsDemo extends StatelessWidget { @override Widget build(BuildContext context) { // Get MediaQueryData MediaQueryData mediaQuery = MediaQuery.of(context); // Get various dimensions double safeAreaTop = mediaQuery.padding.top; double safeAreaBottom = mediaQuery.padding.bottom; double safeAreaLeft = mediaQuery.padding.left; double safeAreaRight = mediaQuery.padding.right; return Scaffold( body: SafeArea( child: Column( children: [ Text('Safe Area Top: $safeAreaTop'), Text('Safe Area Bottom: $safeAreaBottom'), Text('Safe Area Left: $safeAreaLeft'), Text('Safe Area Right: $safeAreaRight'), ], ), ), ); } }
Responsive Layouts
1. Creating Responsive Widgets
class ResponsiveContainer extends StatelessWidget { @override Widget build(BuildContext context) { double screenWidth = MediaQuery.of(context).size.width; return Container( // Width is 90% of screen width on small screens, // 70% on medium screens, and 50% on large screens width: screenWidth < 600 ? screenWidth * 0.9 : screenWidth < 1200 ? screenWidth * 0.7 : screenWidth * 0.5, padding: EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.circular(8), ), child: Text( 'Responsive Container', style: TextStyle(color: Colors.white), ), ); } }
2. Orientation-Specific Layouts
class OrientationAwareLayout extends StatelessWidget { @override Widget build(BuildContext context) { Orientation orientation = MediaQuery.of(context).orientation; return Scaffold( appBar: AppBar(title: Text('Orientation Demo')), body: orientation == Orientation.portrait ? _buildPortraitLayout() : _buildLandscapeLayout(), ); } Widget _buildPortraitLayout() { return Column( children: [ Expanded(child: Container(color: Colors.blue)), Expanded(child: Container(color: Colors.green)), ], ); } Widget _buildLandscapeLayout() { return Row( children: [ Expanded(child: Container(color: Colors.blue)), Expanded(child: Container(color: Colors.green)), ], ); } }
Advanced Usage
1. Custom Screen Size Utilities
class ScreenUtil { static late MediaQueryData _mediaQueryData; static late double screenWidth; static late double screenHeight; static late double blockSizeHorizontal; static late double blockSizeVertical; static late double _safeAreaHorizontal; static late double _safeAreaVertical; static late double safeBlockHorizontal; static late double safeBlockVertical; void init(BuildContext context) { _mediaQueryData = MediaQuery.of(context); screenWidth = _mediaQueryData.size.width; screenHeight = _mediaQueryData.size.height; blockSizeHorizontal = screenWidth / 100; blockSizeVertical = screenHeight / 100; _safeAreaHorizontal = _mediaQueryData.padding.left + _mediaQueryData.padding.right; _safeAreaVertical = _mediaQueryData.padding.top + _mediaQueryData.padding.bottom; safeBlockHorizontal = (screenWidth - _safeAreaHorizontal) / 100; safeBlockVertical = (screenHeight - _safeAreaVertical) / 100; } } // Usage class ResponsiveWidget extends StatelessWidget { @override Widget build(BuildContext context) { ScreenUtil().init(context); return Container( width: ScreenUtil.blockSizeHorizontal * 50, // 50% of screen width height: ScreenUtil.blockSizeVertical * 30, // 30% of screen height child: YourContent(), ); } }
2. Device Type Detection
enum DeviceType { mobile, tablet, desktop, } class DeviceInfo { static DeviceType getDeviceType(BuildContext context) { double width = MediaQuery.of(context).size.width; if (width < 600) { return DeviceType.mobile; } else if (width < 1200) { return DeviceType.tablet; } else { return DeviceType.desktop; } } static bool isMobile(BuildContext context) { return getDeviceType(context) == DeviceType.mobile; } static bool isTablet(BuildContext context) { return getDeviceType(context) == DeviceType.tablet; } static bool isDesktop(BuildContext context) { return getDeviceType(context) == DeviceType.desktop; } }
Best Practices
1. Responsive Dimensions
// ✅ Good: Use relative dimensions Container( width: MediaQuery.of(context).size.width * 0.8, // 80% of screen width height: 50, child: YourWidget(), ) // ❌ Bad: Hard-coded dimensions Container( width: 300, // Fixed width might not work well on all screens height: 50, child: YourWidget(), )
2. Layout Constraints
// ✅ Good: Use constraints for better control Container( constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width * 0.8, minWidth: 200, ), child: YourWidget(), ) // ❌ Bad: No constraints Container( width: MediaQuery.of(context).size.width * 0.8, child: YourWidget(), )
3. Device Orientation Handling
// ✅ Good: Handle both orientations Widget build(BuildContext context) { return OrientationBuilder( builder: (context, orientation) { return GridView.count( crossAxisCount: orientation == Orientation.portrait ? 2 : 3, children: List.generate(6, (index) => YourGridItem()), ); }, ); } // ❌ Bad: Fixed layout regardless of orientation Widget build(BuildContext context) { return GridView.count( crossAxisCount: 2, children: List.generate(6, (index) => YourGridItem()), ); }
Common Issues and Solutions
1. Screen Size Changes
// Problem: Not updating on screen size changes class MyWidget extends StatelessWidget { final double width = 0; // Initialized once @override Widget build(BuildContext context) { return Container(width: width); } } // Solution: Get dimensions in build method class MyWidget extends StatelessWidget { @override Widget build(BuildContext context) { double width = MediaQuery.of(context).size.width; return Container(width: width); } }
2. MediaQuery Access Issues
// Problem: Accessing MediaQuery outside build class MyWidget extends StatelessWidget { final double width = MediaQuery.of(context).size.width; // Error! // Solution: Create a method that requires context double getWidth(BuildContext context) { return MediaQuery.of(context).size.width; } @override Widget build(BuildContext context) { return Container(width: getWidth(context)); } }
Conclusion
Working with screen dimensions in Flutter requires:
- Understanding MediaQuery and its properties
- Implementing responsive layouts
- Handling different orientations
- Using relative dimensions instead of fixed values
- Following best practices for different screen sizes
Remember to:
- Always get dimensions within the build method
- Consider safe areas and system UI
- Use relative dimensions for better responsiveness
- Handle different orientations and screen sizes
- Implement proper constraints for better control
By following these guidelines, you can create Flutter applications that work well across different screen sizes and orientations.