Back to Posts

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:

  1. Understanding MediaQuery and its properties
  2. Implementing responsive layouts
  3. Handling different orientations
  4. Using relative dimensions instead of fixed values
  5. 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.