likes
comments
collection
share

使跨平台Flutter登录页响应

作者站长头像
站长
· 阅读数 13

目标:我们的目标是让Flutter页面相应Web和Native应用程序。

Web登录页:

使跨平台Flutter登录页响应

Native登录屏幕:

使跨平台Flutter登录页响应

介绍

有时候在台式机/平板这样的大屏幕上看起来很棒。但是,当网页放在较小的屏幕时,它的小部件会溢出,如下所示:

使跨平台Flutter登录页响应

在手机屏幕的Native环境中,它看起来像这样:

使跨平台Flutter登录页响应

在这篇文章中,我将展示如何:

  • 实施StatelessWidget ResponsiveWidget以动态屏幕尺寸。
  • 使登录页的主体适合大屏幕和小屏幕
  • 调整登录页的标题以及在较小的屏幕上显示菜单图标。

一、ResponsiveWidget实用类

让我们实现一个ResponsiveWidget使用LayoutBuilder的StatefulWidget。LayoutBuilder是一个小部件,它构建一个可以依赖于父小部件大小的小部件树。此类负责检测屏幕储存,并将它们放入三个之一:大、中和小。它具有实用的静态函数/方法来检查屏幕尺寸。

我将使用MediaQuery访问屏幕的大小。这就是我将如何使用以像素为单位的屏幕宽度来检查屏幕的大小。

class ResponsiveWidget {
    ...
    // 大屏是任何宽度大于1200像素的屏幕
    static bool isLargeScreen(BuildContext context) {
        return MediaQuery.of(context).size.width > 1200;
    }
    // 小屏幕时宽度小于800像素的人格屏幕
    static bool isSmallScreen(BuildContext context) {
        return MediaQuery.of(context).size.width < 800;
    }
    // 中等屏幕时宽度小于1200像素的任何屏幕以及大于800像素的屏幕
    static bool isMediumScreen(BuildContext context) {
        return MediaQuery.of(context).size.width > 800 && MediaQuery.of(context).size.width < 1200;
    }
}

二、调整登录页的主体

为了使其具有响应性,我们需要为屏幕采用不同的设计实现。为简单起见,我将在本教程中仅创建两个布局:Large和Small。Mediium backet中的任何内容都会退回到Large布局。

class Body extendss StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return SizedBox(
            height: 600,
            child: Stack(
                fit: StackFit.expand,
                children: <Widget>[
                    addBackground(),
                    addWelcomeText(),
                ],
            ),
        );
    }
}

我们的目标Body小部件build方法看起来像这样:

import 'package:landingpage/utils/responsive_widget.dart';

class Body extends StatelesssWidget {
    @override
    WIdget build(BuildContext context) {
        return ResponsiveWidget(
            largeScreen: LargeScreen(),
            smallScreen: SmallScreen(),
        );
    }
    ...
}

如您所见,responsive_widget.dart并提供了两个实现:LargeScreen()SmallScreen()。其中一个实现将在运行时根据屏幕尺寸进行渲染。您可能已经注意到我没有提供MediumScreen()。在这种情况下,它将回退到LargeScreen()小部件。好了,我们开始编写LargeScreen()。基本上,我们会将现有布局移动到LargeScreen()。此时大屏布局会是这样:

使跨平台Flutter登录页响应 对于SmallScreen(),我们可能需要做一些修补。就像我们需要将东西放在SingleChildScrollView内的Column中,并将所有其他小部件添加为其子项。我们这样做是为了使所有小部件都适合垂直视图,以便在宽度不足以水平方式布局每个小部件都可访问。这是SmallScreen()实现的样子:

此时,小屏幕布局将如下图所示。您会注意到背景图像移到了欢迎文本下方的地步,以及”订阅以随时了解“文本上方。在较大的屏幕上,背景图像朝向页面的右侧。对于移动站点,文本位于图像上方。观察上面的代码片段。较小屏幕上的整体登录页看起来很平衡。

使跨平台Flutter登录页响应

但是,这种布局仍然存在两个问题:首先,用于输入电子邮件的地址EmailBox向左对齐 ,远离右侧。这是因为右填充"74"。我们需要使其在左侧填充相同,以将此框保持在中央。对于较小的屏幕,让我们将EmailBox小部件右填充设置为”4“。

class EmailBox extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return Padding(
            padding: EdgeInsets.only(
                left:  4.0,
                right: ResponsiveWidget.isSmallScreen(context) ? 4 : 74, //Check for screen type
                top: 10,
                bottom: 40),
                ...
            ),
        );
    }
}

其次,您可能会注意到”Subscribe“按钮仍然有溢出文本,如下面屏幕截图所示:

使跨平台Flutter登录页响应 让我们用修复溢出文本问题SubscribeButton。在三个地方,我们需要调整尺寸渲染以适应较小的屏幕。

  • 使按钮上的文本“Subscribe”字体在运行时适应屏幕 。
Text(
    Strings.subscribeButton,
    style: TextStyle(
        color: MyColors.white1,
        fontSize: ResponsiveWidget.isSmallScreen(context)
            ? 12
            : 16,
        letterSpacing: 1,
    ),
),
  • 使文本和图像之间的间距在运行时适配屏幕。在较小的屏幕上设置为4,在中型屏幕上设置为6,在较大的屏幕上设置为8.
SizedBox(
    width: ResponsiveWidget.isSmallScreen(context)
        ? 4
        : ResponsiveWidget.isMediaScreen(context) ? 6 : 8,
),
  • 最后一件事是使图像大小可根据屏幕大小进行调整。
Image.network(
    emailImage,
    color: MyColors.white1,
    width: ResponsiveWidget.isSmallScreen(context)
        ? 12
        : ResponsiveWidget.isMediumScreen(context) ? 12 : 20,
    height: ResponsiveWidget.isSmallScreen(conrext)
        ? 12
        : ResponsiveWidget.isMediumScreen(context) ? 12 : 20,
),

但是,这并不能完全解决问题。对于小屏幕,“订阅”文本和“电子邮件”的图标太多了,无法一起调整。搜索一你在这里的设计必须要有创意。在我的例子中,我只使用电子邮件图像作为按钮,并跳过了按钮上的“订阅”文本。我为按钮与创建了两种不同的变体。一个用于较小的屏幕,另一个用于较大的屏幕。

Widget buildButton(BuildContext context) {
    if (ResponsiveWidget.isSmallScreen(context) {
        return buildSmallButton(context);
    } else {
        return buildLargeButton(context);
    }
}

在这里,我只展示了小按钮的实现。

注意:我正在使用Chrome的检查模式来检查不同屏幕布局 上的布局。

下面的截图显示了小按钮:

使跨平台Flutter登录页响应

在这一点上,我们已经使登录页面的主体相应。现在让标题相应。

三、调整登录页的标题

在大屏幕上,有足够的空间显示所有导航链接。然而,就较小的屏幕而言,没有足够的空间来显示彼此相邻的所有链接。对于较小的屏幕,显示菜单图标是有意义的。单击菜单图标可以调出所有链接。省市县菜单图标交互超出了文本的范围。

注意:`Image.network`需要替换`Image.asset`为Native实现。

使跨平台Flutter登录页响应

因此,这就是让登录页相应所有屏幕形状因素的结论。

四、在Native环境中运行

您可能想要进行一些更改以适应Native代码。

  • Image.network需要替换为Image.asset
  • flutter_web需要替换为它的原生变体flutter

Native平台的相应式页面在Android中如下所示:

使跨平台Flutter登录页响应

原文翻译博客:Maling Cross-platform Flutter Landing Page Responsive