此博客适用于希望应用现有Android知识的Android开发人员使用Flutter构建移动应用程序。在这篇博客中,我们将探讨Flutter中FrameLayout的等效设计小部件。
系列
- 如何在Flutter中设计Activity UI?
- 如何在Flutter中设计LinearLayout?
- 如何在Flutter中设计FrameLayout?(你在这里)
先决条件
此博客已假设您已在计算机中设置了颤振并能够运行Hello World应用程序。如果您尚未安装颤振,请从此处开始。
Dart基于面向对象的概念,因此作为android java开发人员,您将能够轻松地捕获dart。
让我们开始吧
FrameLayout
是开发Android Designs时经常使用的布局之一。我们定义FrameLayout
添加在堆栈中绘制的单个或多个子视图,最近添加的子项位于顶部。下面展示了我们如何在Android中实现它。
https://stackoverflow.com/questions/25679369/what-does-framelayout-do
FrameLayout
在Android中主要用于两种情况。
- 在另一个子视图的顶部绘制视图,即以Stack的形式重叠视图,最近添加的子项位于顶部。
- 它被用作绘图的容器
Fragments
。
Android的第二个原因是正确的,但是因为一切都是一个小部件,这就是为什么这个概念Fragment
不适用于颤动,而是我们使用小部件。
现在第一个用例非常明显的设计。因此,颤动提供了一个行为相同的小部件FrameLayout
。是的,我知道它的Stack小部件,因为我在第一个用例中使用了粗体字。
堆
堆叠将其子项相对于其框的边缘定位。FrameLayout
当你想以一种简单的方式重叠几个孩子时,这个类相当于并且它更有用,例如,有一些文本和一个图像,用渐变覆盖,并在底部附加一个按钮。
https://flutter.io/widgets/layout/
这就是我们在颤动中定义Stack的方式。
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text("FrameLayout"),
),
body: new Container(
constraints: new BoxConstraints.expand(),
color: Colors.tealAccent,
child: new Stack(
children: [
Container(
height: 200.0,
width: 200.0,
color: Colors.red,
),
Container(
height: 150.0,
width: 150.0,
color: Colors.blue,
),
Container(
height: 100.0,
width: 100.0,
color: Colors.green,
),
Container(
height: 50.0,
width: 50.0,
color: Colors.yellow,
),
],
),
),
),
);
}
}
以下是上述代码的输出。
截图1
正如我们所知,FrameLayout
子视图是以堆栈的形式绘制的,根据它们定义的顺序,它是一个在另一个的顶部。第一个孩子将在底部,最后一个定义孩子将在顶部。
Stack小部件使用相同的概念。首先定义的子窗口小部件children:<Widget>[]
将位于底部,最后一个项目children:<Widget>[]
将位于顶部。
1. android:gravity
这是在父布局中定义的,因为FrameLayout
没有android:gravity
属性,需要layout_gravity
为每个子节点分配才能实现android:gravity
行为。
但是Stack向前迈出了一步并且提供android:gravity
了构建中的行为,这可以使用Stack.alignment属性来实现,该属性接受AlignmentDirectional
具有预定义枚举的对象AlignmentDirectional.topStart
,AlignmentDirectional.center
等等。
由于android:gravity
在父布局中定义,我们将在父级中定义Stack.alignment,这也是我们的Stack
小部件。这是您在上面的示例中定义的方式。
child: new Stack(
alignment: AlignmentDirectional.center,
children: [
...//all your child widgets
],
)
默认情况下,AlignmentDirectional.topStart
如果不为alignment属性指定任何值,则需要执行此操作。您可以参考Screenshot-1
我们未定义任何对齐值的位置,默认情况下将其与顶部起始角对齐。
关于颤动的美丽是有命名惯例,你可以弄清楚它是什么意思。从alignment属性枚举名称,您可以识别它将要执行的操作。AlignmentDirectional.topStart
将设置Stack小部件顶角的子窗口小部件,依此类推。这就是它与其他AlignmentDirectional
值的关系。
顶部重力
中心引力
Bottom gravity
注意 :
- 如果我们没有为Stack定义任何大小,那么它将采用其父大小即
match_parent
。在上面的示例中,我们Container
使用扩展使用BoxConstraints.expand()
它以便它可以占用所有可用空间,即在我们的情况下可以通过tealAccent
颜色识别的整个屏幕。由于我们没有定义任何大小,Stack
因此它将与其父级即整个屏幕一样大,而Stack.alignment属性将根据我们的Container
大小的堆栈大小工作。 - 如果我们没有
Stack
为父级定义任何大小,Stack
那么将从其可用子级中获取最大大小,即wrap_content
。因此,Stack.alignment属性将根据堆栈的大小对齐小部件。下面是我们BoxConstraints.expand()
从中删除约束时的输出Container
。
2. android:layout_gravity
android:layout_gravity
是观点的外部引力。指定视图应触及其父边框的方向。这是我们大部分时间都在使用的FrameLayout
。为了添加此行为Stack
,您需要将子项包装在Align
与layout_gravity
Android 中一样的小部件中。这是您Align
为每个孩子定义小部件的方式。
截图2
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text("FrameLayout"),
),
body: new Container(
color: Colors.tealAccent,
child: new Stack(
children: [
Align(
child: Container(
height: 200.0,
width: 200.0,
color: Colors.red,
),
alignment: AlignmentDirectional.topStart,
),
Align(
child: Container(
height: 150.0,
width: 150.0,
color: Colors.blue,
),
alignment: AlignmentDirectional.topEnd,
),
Align(
child: Container(
height: 100.0,
width: 100.0,
color: Colors.green,
),
alignment: AlignmentDirectional.bottomStart,
),
Align(
child: Container(
height: 50.0,
width: 50.0,
color: Colors.yellow,
),
alignment: AlignmentDirectional.bottomEnd,
),
],
),
),
),
);
}
}
根据上面的代码,我们使用Align.alignment属性将子对齐在四个角上。如果我们没有Stack
使用Align
窗口小部件定义任何大小,则默认情况下Stack
会扩展到可用空间,即我们的情况下的整个屏幕,然后它将根据可用空间对齐窗口小部件,这就是为什么我们能够看到tealAccent
没有颜色的原因BoxConstraints.expand()
。
让我们在Green box小部件中使用Align.alignment属性,看看它的外观。
顶部对齐
中心路线
底部对齐
3.Positioned(定位)
现在,这是我们在Stack中获得的奖金小部件。目前,没有位置行为FrameLayout
。定位小部件只是一个小部件,可以控制a的子节点所在的Stack
位置。要定义子窗口小部件的位置,Stack
我们需要将子窗口包装在Positioned
窗口小部件中top
,bottom
left
并right
根据需要使用和属性定义位置。
以下是定义定位小部件的示例代码。
截图-3
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(
title: new Text("FrameLayout"),
),
body: new Container(
constraints: BoxConstraints.expand(),
color: Colors.tealAccent,
child: new Stack(
children: [
Positioned(
child: Container(
height: 200.0,
width: 200.0,
color: Colors.red,
),
top: 10.0,
left: 10.0,
),
Positioned(
child: Container(
height: 150.0,
width: 150.0,
color: Colors.blue,
),
top: 30.0,
right: 50.0,
),
Positioned(
child: Container(
height: 100.0,
width: 100.0,
color: Colors.green,
),
bottom: 100.0,
left: 30.0,
),
Positioned(
child: Container(
height: 50.0,
width: 50.0,
color: Colors.yellow,
),
bottom: 50.0,
right: 100.0,
),
],
),
),
),
);
}
}
从Screenshot-3
输出中,您可以看到小部件与给定位置对齐。您还可以定义Positioned
小部件的宽度和高度。
结论
FrameLayout
最常用于Android。使用widget Stack
等附加功能可以轻松实现重叠小Positioned
部件。希望在即将到来的博客中涵盖更多主题。我已经创建了一个示例应用程序来参考堆栈属性FrameLayout
。您可以单击工具栏图标以查看Positioned
Widget 的输出。
如果您对想要在Flutter学习的Android主题有任何建议,请在评论中告诉我。
在这里查看flutter for android示例。
谢谢 !!!
如果您觉得这篇文章有帮助。请喜欢,分享和鼓掌,这样其他人就会在Medium上看到这个。如果您有任何问题或建议,请在博客上发表评论或在Twitter,GitHub或Reddit上点击我。
要获得即将发布的博客的最新更新,您可以关注我的媒体,Twitter,GitHub或Reddit。