在 Flutter 中创建响应式布局的 3 个方式

5810次阅读  |  发布于2年以前

最简单的方法,使您的应用程序响应所有屏幕大小(移动,平板电脑,桌面)。

我第一次使用“ Flutter”框架的经历是开发一个物联网网络应用的移动版本。所以基本上,在创建 UI 时,我不担心响应屏幕。这是因为我的应用程序只用于移动设备。

但是在我的第三个项目中,我的老板要求我帮助仓库中的流程实现无纸化。我们希望简化工人在监控货物进出仓库之前通常打印文件的过程。主要的要求是,仓库应用程序应该用在平板设备上。因此,这是我第一次学习在 flutter 应用程序中为更大的屏幕制作小部件。

在学习了一些资源之后,我决定开发一个适用于所有设备的应用程序。工作人员可以在手机上安装应用程序,也可以在仓库的桌面上打开应用程序。这里有 3 个选项,我已经为你收集了如何在颤动应用程序响应布局。

三种方式:

在这个博客中,我们将探索如何使你的应用程序布局适应你的屏幕的 3 个例子。好了,我们开始吧..。

1. Dynamic Padding

你可能认为这是没有反应的,但这是处理宽屏的解决方案之一。它通过向父窗口小部件添加水平填充来工作。将根据屏幕宽度动态设置填充值。让我们看看下面的代码:

import 'package:flutter/material.dart';

class ResponsivePadding extends StatelessWidget {
  final Widget child;
  const ResponsivePadding({
    Key? key,
    required this.child,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: MediaQuery.of(context).size.width > 650
          ? EdgeInsets.symmetric(
              horizontal: MediaQuery.of(context).size.width / 3.8)
          : const EdgeInsets.all(0),
      child: child,
    );
  }
}

您可以为上面的代码创建一个新的文件和类。然后在需要限制屏幕宽度时使用它。所有您需要做的就是用 ResponsivePaddingwidget 包装您的屏幕。


@override
Widget build(BuildContext context) {
  return ResponsivePadding(
    child: Scaffold()
....

https://dartpad.dev/?id=49078a3c9643cb65febbece13ed54ee9

responsive padding

2. Layout Builder

LayoutBuilder: 构建一个小部件树,该树可以依赖于父小部件的大小。

顾名思义,此小部件将根据大小限制构建布局。与第一个不同的是,通过这种方式,我们将捕获所有可能的屏幕大小,然后安排布局。假设我们有 3 种布局: 手机、平板电脑和桌面。在每种布局中,我们可以使用不同的小部件。我学习这种方式从 Youtube 的 Flutter 方式,你可以通过参考链接访问视频。让我们先看看响应代码。

在上面的代码中,我们有一个 StatelessWidget 并返回一个 LayoutBuilder。如你所见,我们有 3 个约束宽度。您可以根据需要进行修改。

实例:

我们可以像下面的代码那样使用它:


@override
Widget build(BuildContext context) {
  return Responsive(
    mobile: mobileWidget,
    tablet: tabletWidget,
    desktop: desktopWidget,
  );
}

https://dartpad.dev/?id=027bc67ac129aed523e58e44c647b3c1

layout builder

现在我们有 3 个不同的布局取决于屏幕大小。您可以为每个布局创建自定义小部件。这样,当应用程序在你的手机、平板电脑或桌面上打开时,它们都有自己适当的外观。

3. Extension BuildContext

好吧,这是一个相当中等的水平,但非常体面,易于使用。因为我们将使用一个来自 flutter 的扩展方法和一个通用函数。让我们从定义开始。

泛型函数是用类型参数声明的函数。调用时,使用实际类型而不是类型参数。 https://learn.microsoft.com/en-us/cpp/extensions/generic-functions-cpp-cli?view=msvc-170

对于泛型函数,我们可以根据声明的类型使用函数。所以会更有活力。在 dartlang 中,当类型 声明一个类或函数时,我们通常会遇到这种情况。

Dart 2.7 中引入的扩展方法是向现有库添加功能的一种方法 https://dart.dev/guides/language/extension-methods

现在我们可以为当前框架创建新的函数。

我们有 BuildContext。众所周知,BuildContext 处理小部件在小部件树中的位置。那么..。我们将在所有的小部件树中有一个上下文。如果没有上下文,则不会呈现小部件。

现在我们将为 BuildContext 创建一个扩展方法来执行 Responsive 布局:

extension Responsive on BuildContext {
  T responsive<T>(
    T defaultVal, {
    T? sm,
    T? md,
    T? lg,
    T? xl,
  }) {
    final wd = MediaQuery.of(this).size.width;
    return wd >= 1280
        ? (xl ?? lg ?? md ?? sm ?? defaultVal)
        : wd >= 1024
            ? (lg ?? md ?? sm ?? defaultVal)
            : wd >= 768
                ? (md ?? sm ?? defaultVal)
                : wd >= 640
                    ? (sm ?? defaultVal)
                    : defaultVal;
  }
}

使用这段代码,我们可以得到与 LayoutBuilder 相同的结果,但是代码更简单。


@override
Widget build(BuildContext context) {
  return Container(
    child: context.responsive<Widget>(
      mobileWidget, // default
      md: tabletWidget, // medium
      lg: desktopWidget, // large
    ),
  );
}

https://dartpad.dev/?id=59656d666468db4c86d2c71362c6dcb4

正如我之前所说,这个方法是通用的,我们可以定义一个函数来返回一个数字或者其他什么。让我们试试下面的例子。我们何时以及如何使用它。

另一个在“ flutter”中使用网格视图的例子


@override
Widget build(BuildContext context) {
  return GridView.count(
    crossAxisCount: context.responsive<int>(
      2, // default
      sm: 2, // small
      md: 3, // medium
      lg: 4, // large
      xl: 5, // extra large screen
    ),
.......

响应式网格视图响应式网格视图

https://dartpad.dev/?id=925bbdc793dc6b529cb07eb636338ac9

好了,这是 3 种方法,使您的 Flutter 应用程序有一个响应布局。您可以根据需要更改断点值。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8