版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/qiyei2009/article/details/84203422

1 Flutter布局浅述

对于一个应用来说,开发UI界面是很基础的一个工作。Flutter中的布局是直接写在代码中的,没有像Android一样使用xml来布局,这一点与RN中使用jsx来布局类似,它遵循的也是一切都是widget的思想。因此Flutter 中UI界面的布局就是组合各种widget的过程。我们可以参考下面的一段话

    In Android, the View is the foundation of everything that shows up on the screen. Buttons, toolbars, and inputs, everything is a View. In Flutter, the rough equivalent to a View is a Widget. Widgets don’t map exactly to Android views, but while you’re getting acquainted with how Flutter works you can think of them as “the way you declare and construct UI”.

大意是在Android中,View是屏幕上显示的所有内容的基础, 按钮、工具栏、输入框等一切都是View。 在Flutter中,View相当于是Widget。所以在Android中我们把所有的UI元素都看成View,在Flutter中widget就类似于View

与Android不同的是,Flutter提供的widget是在是太多了,对于相同的UI界面也可以使用不同的widget来实现,不过在Flutter中有一个原则,那就是尽量使用轻量级的widget来实现

关于如何在Flutter中进行布局,我们还是来参考官方的例子吧
https://flutter.io/docs/development/ui/layout

打开这个例子可以看到Flutter如何教我们布局,下面大体说以下步骤

2 布局拆分

第一步是将布局拆分成基本的元素:
找出行和列.
布局包含网格吗?
有重叠的元素吗?
是否需要选项卡?
注意需要对齐、填充和边框的区域.

首先,确定更大的元素。在这个例子中,四个元素排列成一列:一个图像,两个行和一个文本块

其实这个和Android中的布局类似,如上的布局,在Android中我们也会采用一个线性布局,child分别是imageview,线性布局 线性布局 TextView。

3 确定根布局

由于我们一般会遵循MD设计,因此可以先写出如下的根布局

class MyApp extends StatelessWidget {@overrideWidget build(BuildContext context) {// TODO: implement buildreturn MaterialApp(title: "Flutter Layout Demo",home: Scaffold(appBar: AppBar(centerTitle: true,title: Text("Flutter Layout Demo"),),body: ,),);}
}

下面开始布局body部分了,body部分我们可以采用一个Column或者ListView,官方是ListView 可能主要是怕屏幕空间不够吧。

4 布局Image

我们还是按照官方的布局来。首先布局ImageView

body: ListView(children: <Widget>[Image.asset("assets/images/lake.jpg",height: 240.0,fit: BoxFit.cover,),],),

这里首先把lake.jpg拷贝到工程的assets/images目录下,并且在pubspec.yaml 文件中修改如下

  assets:- assets/images/lake.jpg

运行Demo,我们的效果如下:

5 布局标题行

看下图的标题行

可以看到,首先是一个Row widget,它有三个child一列文字,一个星形图标和一个数字,第一个child是一个Column布局,有两个child,包含2行文字
另外,第一列占用大量空间,所以它必须包装在Expanded widget中。
因此布局如下:

Widget titleSection = Container(padding: EdgeInsets.all(32.0),child: Row(//3个child 水平排列children: <Widget>[//占满剩余空间Expanded(// 2 个child竖直排列child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[Container(padding: EdgeInsets.only(bottom: 8.0),child: Text("Oeschinen Lake Campground",style: TextStyle(fontWeight: FontWeight.bold),),),Text("Kandersteg, Switzerland",style: TextStyle(color: Colors.grey[500]),)],),),Icon(Icons.star,color: Colors.red[500],),Text("41"),],),);

接着,修改我们的ListView如下:

// TODO: implement buildreturn MaterialApp(title: "Flutter Layout Demo",theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(centerTitle: true,title: Text("Flutter Layout Demo"),),body: ListView(children: <Widget>[Image.asset("assets/images/lake.jpg",height: 240.0,fit: BoxFit.cover,),titleSection,],),),);

运行效果如下:

6 实现Button布局

对于Button布局,可以看出这首先是一个Row布局,然后有三个child

这里我们参考官方的例子,写出一个函数来创建布局

  /// 构建buttonColumn _buildButtonColumn(BuildContext context, IconData icon, String label) {Color color = Theme.of(context).primaryColor;return Column(mainAxisSize: MainAxisSize.min,mainAxisAlignment: MainAxisAlignment.center,//列布局children: <Widget>[Icon(icon,color: color,),Container(margin: EdgeInsets.only(top: 8.0),child: Text(label,style: TextStyle(fontSize: 12.0,fontWeight: FontWeight.w400,color: color,),),)],);}

函数调用如下:

    Widget buttonSection = Container(child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: <Widget>[_buildButtonColumn(context, Icons.call, "Call"),_buildButtonColumn(context, Icons.near_me, "Route"),_buildButtonColumn(context, Icons.share, "Share"),],),);

需要说明一下的是官方主轴方向通过 MainAxisAlignment.spaceEvenly 平均的分配每个列占据的行空间,我这里是MainAxisAlignment.spaceAround,注意这二者之间的细微差别。最后运行效果如下:

7 布局Text文本

关于Text文本的布局就很简单了,这里不再细说了,可以参考官方例子。下面看一下完成后的例子
代码

void main() => runApp(MyApp());class MyApp extends StatelessWidget {var text =  '''
Lake Oeschinen lies at the foot of the Blüemlisalp in the Bernese Alps. Situated 1,578 meters above sea level, it is one of the larger Alpine Lakes. A gondola ride from Kandersteg, followed by a half-hour walk through pastures and pine forest, leads you to the lake, which warms to 20 degrees Celsius in the summer. Activities enjoyed here include rowing, and riding the summer toboggan run.''';@overrideWidget build(BuildContext context) {Widget titleSection = Container(padding: EdgeInsets.all(32.0),child: Row(//3个child 水平排列children: <Widget>[//占满剩余空间Expanded(// 2 个child竖直排列child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: <Widget>[Container(padding: EdgeInsets.only(bottom: 8.0),child: Text("Oeschinen Lake Campground",style: TextStyle(fontWeight: FontWeight.bold),),),Text("Kandersteg, Switzerland",style: TextStyle(color: Colors.grey[500]),)],),),Icon(Icons.star,color: Colors.red[500],),Text("41"),],),);Widget buttonSection = Container(child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround,children: <Widget>[_buildButtonColumn(context, Icons.call, "Call"),_buildButtonColumn(context, Icons.near_me, "Route"),_buildButtonColumn(context, Icons.share, "Share"),],),);Widget textSection = Container(padding: EdgeInsets.all(32.0),child: Text(text,softWrap: true,),);// TODO: implement buildreturn MaterialApp(title: "Flutter Layout Demo",theme: ThemeData(primarySwatch: Colors.blue,),home: Scaffold(appBar: AppBar(centerTitle: true,title: Text("Flutter Layout Demo"),),body: ListView(children: <Widget>[Image.asset("assets/images/lake.jpg",height: 240.0,fit: BoxFit.cover,),titleSection,buttonSection,textSection,],),),);}/// 构建buttonColumn _buildButtonColumn(BuildContext context, IconData icon, String label) {Color color = Theme.of(context).primaryColor;return Column(mainAxisSize: MainAxisSize.min,mainAxisAlignment: MainAxisAlignment.center,//列布局children: <Widget>[Icon(icon,color: color,),Container(margin: EdgeInsets.only(top: 8.0),child: Text(label,style: TextStyle(fontSize: 12.0,fontWeight: FontWeight.w400,color: color,),),)],);}
}

运行效果

8 Flutter布局总结

1 Flutter的布局一切都是widget,布局过程就是widget的组合
2 Flutter布局中需要清楚的划分Row Column Stack ListView GridView等
3 布局过程中的margin padding等可考虑使用Container
4 对于有状态的Widget需要使用StatefulWidget子类来实现
5 对于同一布局能用多种不同的widget来实现的,尽量使用轻量级的widget

参考 https://flutter.io/docs/development/ui/layout

浅谈Flutter UI布局相关推荐

  1. 浅谈Flutter的状态State

    重要消息 网易云[玩转大前端]配套课程 EDU配套 教程 Flutter开发的点滴积累系列文章 一行代代码置灰应用?对就是这么干 本方主要内容为 聊一聊 Widget .谈一谈 Context .说一 ...

  2. 浅谈Flutter跨平台调用方式MethodChannel

    Flutter是目前非常流行的跨平台方案,由于它的性能接近于原生应用,因而被越来越多的开发者所采用.既然是跨平台方案,那么久必然存在调用系统功能的需求,在Flutter中,Flutter层与nativ ...

  3. 浅谈车载UI与手机UI的设计区别【萧蕊冰】

    今天的文章来讲一下车载UI与手机UI的设计区别.车载UI也就是汽车UI,现在很多企业在开发产品时,把产品硬件配置提升得很高,几乎与手机同步,所以很多人就会觉得车载UI就跟手机UI没什么区别,其实,这是 ...

  4. 浅谈flutter的优点与缺点

    Google不喜欢MPEG,于是推出了VP8.但打一开始他们就没在将其打造成一个真正的开放标准上做任何努力. Google不喜欢HTTP,于是推出了SPDY.但现在只有Chrome和Google的网页 ...

  5. 浅谈Android五大布局——LinearLayout、FrameLayout和AbsoulteLa

    为什么80%的码农都做不了架构师?>>>    Android的界面是有布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦.组件按照布局的要求依次排列,就组成了 ...

  6. java设置绝对布局_浅谈Java绝对布局 原创

    在 swing 中,除了使用布局管理器之外还可以使用绝对布局.下面我们就来简单了解一下什么是绝对布局. 绝对布局,就是硬性指定组件在容器中的位置和大小,可以使用绝对坐标的方式来指定组件的位置. 使用绝 ...

  7. 浅谈Android五大布局

    来自:http://www.cnblogs.com/wisekingokok/archive/2011/08/23/2150452.html Android的界面是有布局和组件协同完成的,布局好比是建 ...

  8. 浅谈Android五大布局(一)——LinearLayout、FrameLayout和AbsoulteLayout

    Android的界面是有布局和组件协同完成的,布局好比是建筑里的框架,而组件则相当于建筑里的砖瓦.组件按照布局的要求依次排列,就组成了用户所看见的界面.Android的五大布局分别是LinearLay ...

  9. 浅谈从UI设计转前端的坎坷历程

    大家好,我是一个程序员--资深CV工程师(狗头保命)!在此想和大家一起分享一下从UI转前端的坎坷历程,希望能够帮助一些想入坑的朋友们. 加入门派(如何走上UI设计之路) 我大学的专业是计算机科学与技术 ...

最新文章

  1. 数据回发时,维护ASP.NET Tree控件位置
  2. WindowsMobile/Win Form-界面自适应
  3. boost::fusion::detail::and_用法的测试
  4. 悟空分词与mysql结合_Mysql联合查询UNION和UNION ALL的使用介绍
  5. 【算法竞赛学习】气象海洋预测-Task5 模型建立之 SA-ConvLSTM
  6. 用户需求、己、竞争对手的关系
  7. 【2016年第4期】经济发展的顶层设计 企业战略的终极蓝图—— 产业互联网
  8. oppo手机显示andrOid什么意思,OPPO R17 Pro手机状态栏图标分别代表什么意思?
  9. php 付款,php – 接受付款最佳做法
  10. TypeScript算法专题 - blog1.基于TypeScript语言的单链表实现
  11. 网络热词下的民意传播
  12. IoT平台功能架构图
  13. win10环境redis集群搭建(非主从模式)
  14. 计算机的算数逻辑单元控制单元统称为,算术控制单元
  15. 美团买菜助手来了,自动点击,助你买菜
  16. SpringMVC总结笔记
  17. 杂谈:Perl6 树莓Pi Erlang win10 Clojure
  18. RGB565 RGB888
  19. 公司上云在即,给大家分享一份猫厂、鹅厂和菊厂云服务器的测评情况
  20. 通过FAR计算fRR

热门文章

  1. 山东科技职业学院单招计算机,山东科技职业学院单招
  2. python基本内容讲解_Python命名约定基本内容解析
  3. swift 项目_谷歌为何要养苹果的亲儿子Swift?原来意在可微分编程
  4. 游戏本自动掉帧_机 · 科普帖丨如何在夏天告别游戏掉帧的问题
  5. PCL——PCD文件格式分析
  6. Vue的mergeOptions函数分析-下
  7. spring cloud简介之最好参考
  8. Redis实现微博后台业务逻辑系列(八)
  9. The Dandy Lab使用RFID积分方案,提升客户保持率
  10. 一文读懂python本地开发环境配置