【译】Flutter For Android Developers:如何在Flutter中设计FrameLayout。

demo下载

 

此博客适用于希望应用现有Android知识的Android开发人员使用Flutter构建移动应用程序。在这篇博客中,我们将探讨Flutter中FrameLayout的等效设计小部件。

原文:https://medium.com/flutter-community/flutter-for-android-developers-how-to-design-framelayout-in-flutter-93a19fc7e7a6

系列

先决条件

此博客已假设您已在计算机中设置了颤振并能够运行Hello World应用程序。如果您尚未安装颤振,请从此处开始。

Dart基于面向对象的概念,因此作为android java开发人员,您将能够轻松地捕获dart。

让我们开始吧

FrameLayout是开发Android Designs时经常使用的布局之一。我们定义FrameLayout添加在堆栈中绘制的单个或多个子视图,最近添加的子项位于顶部。下面展示了我们如何在Android中实现它。

https://stackoverflow.com/questions/25679369/what-does-framelayout-do

FrameLayout 在Android中主要用于两种情况。

  1. 在另一个子视图的顶部绘制视图,即以Stack的形式重叠视图,最近添加的子项位于顶部。
  2. 它被用作绘图的容器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

注意 :

  1. 如果我们没有为Stack定义任何大小,那么它将采用其父大小即match_parent 。在上面的示例中,我们Container使用扩展使用BoxConstraints.expand()它以便它可以占用所有可用空间,即在我们的情况下可以通过tealAccent颜色识别的整个屏幕。由于我们没有定义任何大小,Stack因此它将与其父级即整个屏幕一样大,而Stack.alignment属性将根据我们的Container大小的堆栈大小工作。
  2. 如果我们没有Stack为父级定义任何大小,Stack那么将从其可用子级中获取最大大小,即wrap_content 。因此,Stack.alignment属性将根据堆栈的大小对齐小部件。下面是我们BoxConstraints.expand()从中删除约束时的输出Container


2. android:layout_gravity

android:layout_gravity是观点的外部引力。指定视图应触及其父边框的方向。这是我们大部分时间都在使用的FrameLayout。为了添加此行为Stack,您需要将子项包装在Alignlayout_gravityAndroid 中一样的小部件中。这是您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窗口小部件中topbottom leftright根据需要使用和属性定义位置。

以下是定义定位小部件的示例代码。

截图-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。您可以单击工具栏图标以查看PositionedWidget 的输出。

如果您对想要在Flutter学习的Android主题有任何建议,请在评论中告诉我。

在这里查看flutter for android示例。

burhanrashid52 / FlutterForAndroidExample
这是我的博客系列“Flutter For Android Developer”的示例应用程序,适用于希望申请的Android开发人员...github.com

谢谢 !!!

如果您觉得这篇文章有帮助。请喜欢,分享和鼓掌,这样其他人就会在Medium上看到这个。如果您有任何问题或建议,请在博客上发表评论或在Twitter,GitHub或Reddit上点击我。

要获得即将发布的博客的最新更新,您可以关注我的媒体,Twitter,GitHub或Reddit。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值