Search code examples
flutterflutter-layoutflutter-web

Creating a responsivness layout for a website


I want to create a website with flutter. Unforunatly I have some problems with coding the layout.

I want to have a responsivness layout, so I tried to find the most common resolutions for mobile, tablet and laptop. This resolutions should help me to decide when the screensize is small, medium or large.

I recently started this project, so I am still a beginner and hope that you guys can help me to figure out, how to solve this error messages.

At the moment I have the problem, that I get this error messages from the code below:

   lib/helpers/responsiveness.dart:16:14: Error: The parameter 'largeScreen' can't have a value of 'null' because of its type 'Widget', but the implicit default value is 'null'.
 - 'Widget' is from 'package:flutter/src/widgets/framework.dart' ('../flutter/packages/flutter/lib/src/widgets/framework.dart').
Try adding either an explicit non-'null' default value or the 'required' modifier.
        this.largeScreen,
             ^^^^^^^^^^^
lib/helpers/responsiveness.dart:17:14: Error: The parameter 'mediumScreen' can't have a value of 'null' because of its type 'Widget', but the implicit default value is 'null'.
 - 'Widget' is from 'package:flutter/src/widgets/framework.dart' ('../flutter/packages/flutter/lib/src/widgets/framework.dart').
Try adding either an explicit non-'null' default value or the 'required' modifier.
        this.mediumScreen,
             ^^^^^^^^^^^^
lib/helpers/responsiveness.dart:18:14: Error: The parameter 'smallScreen' can't have a value of 'null' because of its type 'Widget', but the implicit default value is 'null'.
 - 'Widget' is from 'package:flutter/src/widgets/framework.dart' ('../flutter/packages/flutter/lib/src/widgets/framework.dart').
Try adding either an explicit non-'null' default value or the 'required' modifier.
        this.smallScreen,
             ^^^^^^^^^^^
lib/helpers/responsiveness.dart:47:18: Warning: Operand of null-aware operation '??' has type 'Widget' which excludes null.
 - 'Widget' is from 'package:flutter/src/widgets/framework.dart' ('../flutter/packages/flutter/lib/src/widgets/framework.dart').
          return mediumScreen ?? largeScreen;  //if medium screen is null then return large screen
                 ^
lib/helpers/responsiveness.dart:50:16: Warning: Operand of null-aware operation '??' has type 'Widget' which excludes null.
 - 'Widget' is from 'package:flutter/src/widgets/framework.dart' ('../flutter/packages/flutter/lib/src/widgets/framework.dart').
        return smallScreen ?? largeScreen;    //if small screen is null then return large screen
               ^
Failed to compile application.

here my code:

import 'package:flutter/material.dart';

const int largeScreenSize = 1366;     //laptop resolution
const int mediumScreenSize = 768;     //Tablet resolution
const int smallScreenSize = 360;      //mobile resolution
const int customScreenSize = 1100;    //most common custom resolution

class ResponsiveWidget extends StatelessWidget {
  final Widget largeScreen;
  final Widget mediumScreen;
  final Widget smallScreen;
  //final Widget customScreen;

  const ResponsiveWidget(
      {Key? key, @required
        this.largeScreen,
        this.mediumScreen,
        this.smallScreen,
        //this.customScreen
      })
      : super(key: key);

static bool isSmallScreen (BuildContext context) =>       //smaller than smallScreenSize = small screen
    MediaQuery.of(context).size.width < smallScreenSize;

static bool isMediumScreen (BuildContext context) =>      //larger or equal than mediumScreenSize but  smaller than largeScreenSize = medium screen
    MediaQuery.of(context).size.width >= mediumScreenSize &&
    MediaQuery.of(context).size.width < largeScreenSize;

static bool isLargeScreen (BuildContext context) =>      //larger or equal than largeScreen = large screen
    MediaQuery.of(context).size.width >= largeScreenSize;

static bool isCustomScreen (BuildContext context) =>    //everything between medium and custom screen size is custom screen size
    MediaQuery.of(context).size.width >= mediumScreenSize &&
    MediaQuery.of(context).size.width <= customScreenSize;


  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (context, constraints){
      double _width = constraints.maxWidth;
      if (_width >= largeScreenSize) {
        return largeScreen;
      }
      else
        if (_width < largeScreenSize && _width >= mediumScreenSize){
          return mediumScreen ?? largeScreen;  //if medium screen is null then return large screen
        }
        else {
        return smallScreen ?? largeScreen;    //if small screen is null then return large screen
      }
    });
  }
}

Solution

  • Based on your constructors you must provide all three different screen sizes

     final Widget largeScreen;
      final Widget mediumScreen;
      final Widget smallScreen;
    

    Without the nullable operator ? means you must provide a value

    Try adding either an explicit non-'null' default value or the 'required' modifier. this.largeScreen,

    in this case you can solve this by making your widgets nullable

     final Widget? largeScreen;
      final Widget? mediumScreen;
      final Widget? smallScreen;
    
    

    also here is a better responsive widget using LayoutBuilder

    // ignore_for_file: type_annotate_public_apis, sort_constructors_first
    
    import 'package:flutter/material.dart';
    
    class ResponsiveWidget extends StatelessWidget {
      final Widget? largeScreen;
      final Widget? mediumScreen;
      final Widget? smallScreen;
      const ResponsiveWidget({
        Key? key,
        this.largeScreen,
        this.mediumScreen,
        this.smallScreen,
      }) : super(key: key);
      static bool isSmallScreen(BuildContext context) {
        return MediaQuery.of(context).size.width < 800;
      }
    
      static bool isLargeScreen(BuildContext context) {
        return MediaQuery.of(context).size.width > 800;
      }
    
      static bool isMediumScreen(BuildContext context) {
        return MediaQuery.of(context).size.width >= 800 &&
            MediaQuery.of(context).size.width <= 1200;
      }
    
      @override
      Widget build(BuildContext context) {
        return LayoutBuilder(
          builder: (BuildContext context, BoxConstraints constraints) {
            if (constraints.maxWidth > 1200) {
              return Container(child: largeScreen ??smallScreen);
            } else if (constraints.maxWidth <= 1200 &&
                constraints.maxWidth >= 800) {
              return Container(child: mediumScreen??smallScreen);
            } else {
              return smallScreen!;
            }
          },
        );
      }
    }