为网站创建响应式布局

Creating a responsivness layout for a website

我想用 flutter 创建一个网站。不幸的是,我在布局编码方面遇到了一些问题。

我想要一个响应式布局,所以我试图找到手机、平板电脑和笔记本电脑最常见的分辨率。这个分辨率应该可以帮助我决定屏幕尺寸是小、中还是大。

我最近开始这个项目,所以我还是个初学者,希望你们能帮我弄清楚,如何解决这个错误消息。

目前我遇到了问题,我从下面的代码中得到了这个错误信息:

   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.

这是我的代码:

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
      }
    });
  }
}

根据您的构造函数,您必须提供所有三种不同的屏幕尺寸

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

没有可空运算符?意味着您必须提供一个值

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

在这种情况下,您可以通过使小部件可为空来解决此问题

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

这里还有一个更好的响应小部件,使用 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!;
        }
      },
    );
  }
}


对于 Flutter 中的响应式布局,您可以使用 flutter_bootstrap 包。这个包太好用了。检查此页面 flutter_bootstrap