使跨平台Flutter登录页响应
目标:我们的目标是让Flutter页面相应Web和Native应用程序。
Web登录页:
Native登录屏幕:
介绍
有时候在台式机/平板这样的大屏幕上看起来很棒。但是,当网页放在较小的屏幕时,它的小部件会溢出,如下所示:
在手机屏幕的Native环境中,它看起来像这样:
在这篇文章中,我将展示如何:
- 实施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()
。此时大屏布局会是这样:
对于SmallScreen()
,我们可能需要做一些修补。就像我们需要将东西放在SingleChildScrollView
内的Column
中,并将所有其他小部件添加为其子项。我们这样做是为了使所有小部件都适合垂直视图,以便在宽度不足以水平方式布局每个小部件都可访问。这是SmallScreen()
实现的样子:
此时,小屏幕布局将如下图所示。您会注意到背景图像移到了欢迎文本下方的地步,以及”订阅以随时了解“文本上方。在较大的屏幕上,背景图像朝向页面的右侧。对于移动站点,文本位于图像上方。观察上面的代码片段。较小屏幕上的整体登录页看起来很平衡。
但是,这种布局仍然存在两个问题:首先,用于输入电子邮件的地址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“按钮仍然有溢出文本,如下面屏幕截图所示:
让我们用修复溢出文本问题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的检查模式来检查不同屏幕布局 上的布局。
下面的截图显示了小按钮:
在这一点上,我们已经使登录页面的主体相应。现在让标题相应。
三、调整登录页的标题
在大屏幕上,有足够的空间显示所有导航链接。然而,就较小的屏幕而言,没有足够的空间来显示彼此相邻的所有链接。对于较小的屏幕,显示菜单图标是有意义的。单击菜单图标可以调出所有链接。省市县菜单图标交互超出了文本的范围。
注意:`Image.network`需要替换`Image.asset`为Native实现。
因此,这就是让登录页相应所有屏幕形状因素的结论。
四、在Native环境中运行
您可能想要进行一些更改以适应Native代码。
Image.network
需要替换为Image.asset
flutter_web
需要替换为它的原生变体flutter
Native平台的相应式页面在Android中如下所示:
原文翻译博客:Maling Cross-platform Flutter Landing Page Responsive