作者:真丶深红骑士
链接:
https://juejin.im/post/5c617e34f265da2d90581613

本文由作者授权发布。

一、前言

前一天学习了 Flutter 基本控件和基本布局,我是觉得蛮有意思的。作为前端开发者,如何开发出好看,用户体验好的界面尤其重要。今天学习的方向主要有三:

  • 1. 加深布局的熟练度。

  • 2. 学习手势,页面跳转交互。

  • 3. 学习动画。

二、布局

因为我是从事 Android 开发,学习了 Flutter 之后,发现其布局和在 Android 下布局是不一样的, Android 布局是在 XML 文件下,直观性强一点,基本是整体到局部,首先是确定根布局是用 LinearLayout 还是 RelativeLayout 或者是 constraintLayout等。而在 Flutter 下,都是由 Widget 来拼接起来,很多时候都是 Row + Column 合成,我自己是在草稿上画出用什么 Widget 来拼出需求布局,然后才去实现。

1.布局一

直接上需求:

需求图

很容易看出三块竖直排列,跟 Widget 用 Column 来实现,局部第一行是 Text ,第二行是 Row 行,但是 Row 并不是都是统一样式,多线程和Java深入是带圆角背景的,下面再仔细讲解,第三行是两个文本(作者文本和时间文本),一个图标,第一个文本很容易想到 Expanded ,当s时间文本和图标摆放后,其会占满剩余主轴空间。

分析布局一

1.1.封装TextStyle和Padding

首先我看到整个布局下字体的颜色至少四种,有加粗和不加粗的,并且有部分加了 padding ,还是封装 TextStyle 和 padding把:

 1    /** 2     * TextStyle:封装 3     * colors:颜色 4     * fontsizes:字体大小 5     * isFontWeight:是否加粗 6     */ 7    TextStyle getTextStyle(Color colors,double fontsizes,bool isFontWeight){ 8      return TextStyle( 9        color:colors,10        fontSize: fontsizes,11        fontWeight: isFontWeight == true ? FontWeight.bold : FontWeight.normal ,12      );13    }14        /**15     * 组件加上下左右padding16     * w:所要加padding的组件17     * all:加多少padding18     */19    Widget getPadding(Widget w,double all){20      return Padding(21        child:w,22        padding:EdgeInsets.all(all),23      );24    }2526    /**27     * 组件选择性加padding28     * 这里用了位置可选命名参数{param1,param2,...}来命名参数,也调用的时候可以不传29     *30     */31    Widget getPaddingfromLTRB(Widget w,{double l,double t,double,r,double b}){32      return Padding(33        child:w,34        padding:EdgeInsets.fromLTRB(l ?? 0,t ?? 0,r ?? 0,b ?? 0),35      );36    }

1.2.实现第一行

因为上面分析,整体是用 Column 来实现,下面实现第一行 Java synchronized原理总结

 1    Widget ColumnWidget = Column( 2      //主轴上设置居中 3      mainAxisAlignment: MainAxisAlignment.center, 4      //交叉轴(水平方向)设置从左开始 5      crossAxisAlignment: CrossAxisAlignment.start, 6      children: <Widget>[ 7        //第一行 8        getPaddingfromLTRB(Text('Java synchronized原理总结', 9          style: getTextStyle(Colors.black, 16,true),10        ),t:0.0),11      ],12    );

1.3.实现第二行

1.3.1实现渐变圆角Text

第二行可以看到 多线程 和 Java深入 是带渐变效果的圆角,一看到这,我是没有头绪的,查了网上的资料发现 Container 是有设置 圆角 和 渐变 属性的:

 1    //抽取第二行渐变text效果 2    Container getText(String text,LinearGradient linearGradient){ 3      return Container( 4        //距离左边距离10dp 5        margin: const EdgeInsets.only(left: 10), 6        //约束 相当于直接制定了该Container的宽和高,且它的优先级要高于width和height 7        constraints: new BoxConstraints.expand( 8          width: 70.0, height: 30.0,), 9        //文字居中10        alignment: Alignment.center,11        child: new Text(12            text,13            style:getTextStyle(Colors.white,14,false),14        ),15        decoration: new BoxDecoration(16          color: Colors.blue,17          //圆角18          borderRadius: new BorderRadius.all(new Radius.circular(6.0)),19          //添加渐变20          gradient:linearGradient,21        ),22      );2324    }
1.3.2.整合第二行
 1//第二行 2    Widget rowWidget = Row( 3      //主轴左边对齐 4      mainAxisAlignment: MainAxisAlignment.start, 5      //交叉轴(竖直方向)居中 6      crossAxisAlignment: CrossAxisAlignment.center, 7      children: <Widget>[ 8        Text("分类:", 9          style: getTextStyle(Colors.blue,14,true),1011        ),12        getText("多线程", l1),13        getText("Java深入", l2),14      ],1516    );1718    //根Widget19    Widget ColumnWidget = Column(20      //主轴上设置居中21      mainAxisAlignment: MainAxisAlignment.center,22      //交叉轴(水平方向)设置从左开始23      crossAxisAlignment: CrossAxisAlignment.start,24      children: <Widget>[25        //第一行26        getPaddingfromLTRB(Text('Java synchronized原理总结',27          style: getTextStyle(Colors.black, 16,true),28        ),t:0.0),29        //第二行30        getPaddingfromLTRB(rowWidget,t:10.0),31      ],32    );

1.4.实现第三行

第三行就简单了,直接一个 Row Widget,内部嵌套 Expanded 、 Text 、 Icon 就Ok了,代码如下:

 1  //第三行 2    Widget rowthreeWidget = Row( 3      mainAxisAlignment: MainAxisAlignment.start, 4      crossAxisAlignment: CrossAxisAlignment.center, 5      children: <Widget>[ 6         new Expanded( 7             child: Text( 8                 "作者:EnjoyMoving", 9                 style: getTextStyle(Colors.grey[400], 14, true),10             ),11         ),12         getPaddingfromLTRB(Text(13           '时间:2019-02-02',14           style: getTextStyle(Colors.black, 14, true),15         ), r :10.0),16         getPaddingfromLTRB(Icon(17           Icons.favorite_border,18           color:Colors.grey[400],19         ),r:0.0)20      ],21    );

1.5.整体

 1    //根Widget 2    Widget ColumnWidget = Column( 3      //主轴上设置居中 4      mainAxisAlignment: MainAxisAlignment.center, 5      //交叉轴(水平方向)设置从左开始 6      crossAxisAlignment: CrossAxisAlignment.start, 7      children: <Widget>[ 8        //第一行 9        getPaddingfromLTRB(Text('Java synchronized原理总结',10          style: getTextStyle(Colors.black, 16,true),11        ),t:0.0),12        //第二行13        getPaddingfromLTRB(rowWidget,t:10.0),14        //第三行15        getPaddingfromLTRB(rowthreeWidget,t:10.0),1617      ],18    );19    return new Scaffold(20        appBar: new AppBar(21          title: new Text('Flutter Demo'),22        ),23        //用card裹住24        body: Card(25              child: Container(26                //高度27                height: 160.0,28                //颜色29                color: Colors.white,30                padding: EdgeInsets.all(10.0),31                child:  Center(32                  child: ColumnWidget,33                )34              ),35          ),36    );

最终效果如下:

布局一实现效果

2.布局二

直接上电影卡片布局,如下:

布局二需求图

大致把图看了一遍,大致框架是最外层是用 Row ,左孩子是图片,右孩子是 Column ,其孩子分为五行,最后一行主演还是用 Row 来实现,上分析图:

布局二分析图

2.1.实现右边图片

 1//根Widget 布局二 开始 2    //右边图片布局 3    Widget LayoutTwoLeft = Container( 4        //这次使用裁剪实现圆角矩形 5        child:ClipRRect( 6          //设置圆角 7          borderRadius: BorderRadius.circular(4.0), 8          child: Image.network( 9            'https://img3.doubanio.com//view//photo//s_ratio_poster//public//p2545472803.webp',10            width: 100.0,11            height: 150.0,12            fit:BoxFit.fill,13          ),1415        ),16    );17        //整体18    Widget RowWidget = Row(19      //主轴上设置居中20      mainAxisAlignment: MainAxisAlignment.start,21      //交叉轴(水平方向)设置从左开始22      crossAxisAlignment: CrossAxisAlignment.center,23      children: <Widget>[24        LayoutTwoLeft,25      ],26    );27

2.2.实现圆形头像

就是用自带的 CircleAvatar 这个 Widget 来实现:

1    //右下角圆形2    CircleAvatar getCircleAvator(String image_url){3      //圆形头像4      return CircleAvatar(5        backgroundColor: Colors.white,6        backgroundImage: NetworkImage(image_url),7      );8    }

2.3.实现右边布局

右布局就是用一个 Column 来实现,一列一列往下实现即可:

 1    //右布局 2    Widget LayoutTwoRightColumn = Column( 3      crossAxisAlignment: CrossAxisAlignment.start, 4      children: <Widget>[ 5        //电影名称 6        Text( 7          '流浪地球', 8          style: getTextStyle(Colors.black, 20.0, true), 9        ),1011        //豆瓣评分12        Text(13          '豆瓣评分:7.9',14          style: getTextStyle(Colors.black54, 16.0, false),15        ),1617        //类型18        Text(19          '类型:科幻、太空、灾难',20          style:getTextStyle(Colors.black54, 16.0, false),21        ),2223        //导演24        Text(25          '导演:郭帆',26          style: getTextStyle(Colors.black54, 16.0, false),27        ),2829        //主演30        Container(31          margin: EdgeInsets.only(top:8.0),32          child:Row(33            children: <Widget>[34              Text('主演:'),35              //以Row从左到右排列头像36              Row(37                children: <Widget>[38                  Container(39                    margin: EdgeInsets.only(left:2.0),40                    child: getCircleAvator('https://img3.doubanio.com//view//celebrity//s_ratio_celebrity//public//p1533348792.03.webp'),41                  ),42                  Container(43                    margin: EdgeInsets.only(left:12.0),44                    child: getCircleAvator('https://img3.doubanio.com//view//celebrity//s_ratio_celebrity//public//p1501738155.24.webp'),45                  ),46                  Container(47                    margin: EdgeInsets.only(left:12.0),48                    child: getCircleAvator('https://img3.doubanio.com//view//celebrity//s_ratio_celebrity//public//p1540619056.43.webp'),49                  ),5051                ],52              ),53            ],54          ),55        ),56      ],57    );5859    //布局二 右布局 用Expanded占满剩余空间60    Widget LayoutTwoRightExpanded = Expanded(61      child:Container(62        //距离左布局1063        margin:EdgeInsets.only(left:10.0),64        //高度65        height:150.0,66        child: LayoutTwoRightColumn,67      ),68    );

右布局用 Expanded 就是为了占满剩余空间。

2.4.整合

 1    //整体 2    Widget RowWidget = Row( 3      //主轴上设置从开始方向对齐 4      mainAxisAlignment: MainAxisAlignment.start, 5      //交叉轴(水平方向)居中 6      crossAxisAlignment: CrossAxisAlignment.center, 7      children: <Widget>[ 8        LayoutTwoLeft, 9        LayoutTwoRightExpanded,10      ],11    );12        return new Scaffold(13        appBar: new AppBar(14          title: new Text('Flutter Demo'),15        ),16        body: Card(17              child: Container(18                //alignment: Alignment(0.0, 0.0),19                height: 160.0,20                color: Colors.white,21                padding: EdgeInsets.all(10.0),22                child:  Center(23                // 布局一24                // child: ColumnWidget,2526                // 布局二27                   child:RowWidget,28                )29              ),30          ),31      );

运行效果图如下:

布局二实现效果图

3.布局三

同样直接上需求:

需求三布局

一看还是根布局直接用 Column ,一行一行实现就可以了,这个布局稍微简单一点,上分析图:

需求三布局分析图

3.1.实现第一行

 1    //布局三开始第一行 2    Widget LayoutThreeOne = Row( 3       children: <Widget>[ 4         Expanded( 5           child: Row( 6             children: <Widget>[ 7               Text('作者:'), 8               Text('HuYounger', 9                  style: getTextStyle(Colors.redAccent[400], 14, false),10               ),11             ],12           )13         ),14         //收藏图标15         getPaddingfromLTRB(Icon(Icons.favorite,color:Colors.red),r:10.0),16         //分享图标17         Icon(Icons.share,color:Colors.black),18       ],19    );

3.2.实现第三行

 1    //布局三开始第三行 2    Widget LayoutThreeThree = Row( 3      children: <Widget>[ 4        Expanded( 5          child: Row( 6            children: <Widget>[ 7              Text('分类:'), 8              getPaddingfromLTRB(Text('开发环境/Android', 9                  style:getTextStyle(Colors.deepPurpleAccent, 14, false)),l:8.0),10            ],11          ),12        ),13        Text('发布时间:2018-12-13'),14      ],15    );

3.3.整合

 1 //布局三整合 2    Widget LayoutThreeColumn = Column( 3      //主轴上设置居中 4      mainAxisAlignment: MainAxisAlignment.center, 5      //交叉轴(水平方向)设置从左开始 6      crossAxisAlignment: CrossAxisAlignment.start, 7      children: <Widget>[ 8        //第一行 9        LayoutThreeOne,10        //第二行11        getPaddingfromLTRB(Text('Android Monitor使用介绍',12              style:getTextStyle(Colors.black, 18, false),13        ),t:10.0),14        //第三行15        getPaddingfromLTRB(LayoutThreeThree,t:10.0),16      ],1718    );19 return new Scaffold(20        appBar: new AppBar(21          title: new Text('Flutter Demo'),22        ),23        body: Card(24              child: Container(25                //alignment: Alignment(0.0, 0.0),26                height: 160.0,27                color: Colors.white,28                padding: EdgeInsets.all(10.0),29                child:  Center(30                // 布局一31                // child: ColumnWidget,3233                // 布局二34                // child:RowWidget,3536                // 布局三37                   child:LayoutThreeColumn,38                )39              ),40          ),41      );42    }

运行效果:


布局三效果图

由于微信字数限制,本文未完,请链接以下地址继续查阅:

https://juejin.im/post/5c617e34f265da2d90581613

推荐阅读:

Android控件人生第一站,小红书任意拖拽标签控件

第一站小红书图片裁剪控件之二,自定义CoordinatorLayout联动效果

第一站仿小红书图片裁剪控件,深度解析大厂炫酷控件

Flutter学习之布局、交互、动画相关推荐

  1. Flutter学习-多子布局Widget

    Flutter学习-多子布局Widget 1. Flex 2. Row组件 2.1 Row组件介绍 2.2 属性解析 2.2.1 mainAxisSize 2.2.2 mainAxisAlignmen ...

  2. Flutter学习-单子布局Widget

    Flutter学习-单子布局Widget 1. 概述 2. Align 2.1 Align的对齐方式 2.2 Align的区域大小控制 2. Center 3. Padding 4. Containe ...

  3. FLUTTER学习笔记--布局

    文章目录 一.线性布局 1.Column 2.Row 3.代码 4.效果 二.弹性布局 1.Flex 2.Expanded(可伸缩组件) 3.代码 4.效果 三.流式布局 1.Wrap(解决内容溢出问 ...

  4. Flutter学习指南:文件、存储和网络

    Flutter学习指南 交互.手势和动画 UI布局和控件 熟悉Dart语言 编写第一个应用 开发环境搭建 本篇文章我们先学习 Flutter IO 相关的基础知识,然后在 Flutter学习指南:交互 ...

  5. iOS程序猿的flutter学习之路

    日常学习Flutter开发的积累 推荐一些平时自己学习Flutter开发当中接触到的优秀文章 -------------------------基础知识 ----------------------- ...

  6. Flutter学习之入门和体验

    作者:真丶深红骑士 链接: https://juejin.im/user/597247ad5188255aed1fbba6 本文由作者授权发布. 01前言 1.什么是Flutter 上周我的一位微信好 ...

  7. flutter scrollview_简单易上手的Flutter学习指南App,2020一起来玩转Flutter吧~

    Flutter是谷歌的移动UI框架,可以快速在iOS.Android.Web和PC上构建高质量的原生用户界面. Flutter可以与现有的代码一起工作.在全世界,Flutter正在被越来越多的开发者和 ...

  8. Flutter 学习

    Flutter 学习 参照:https://book.flutterchina.club/ 参照:https://flutter.cn/docs/development/platform-integr ...

  9. Flutter学习总纲教程

    Flutter学习总纲教程 Flutter Widget 目录 准备 学习Flutter之前,必须要了解(不需要多么精通,但至少要了解)Dart的基础特性. Dart基础特性  ·  Dart 是 G ...

最新文章

  1. OpenNI框架介绍
  2. Hazelcast介绍与使用
  3. Web Storage API的介绍和使用
  4. xcode快捷键(二)
  5. 【numpy】查询手册
  6. [算法笔试题]华为相关复习题(更新中)
  7. 【毕业设计6】基于51单片机的红外避障小车
  8. html 怎么绘制曲线图,用html5绘制折线图的实例代码_html5教程技巧
  9. 【python爬虫】《中华诗词大会》诗词接龙代码实现
  10. golang实现简单rpc调用
  11. 用计算机绘制工作表,实用计算机机械图样绘制技法
  12. 玩转基因组浏览器之使用IGV查看基因结构信息
  13. vivo Z1i的usb调试模式在哪里,打开vivo Z1iusb调试模式的流程
  14. 0315-HttpURLConnection和JASON结合使用(以天气预报为例)
  15. 新买的键盘部分按键不好使失灵
  16. python学习18
  17. python文件的两种编译方法
  18. 零基础想学速写?要想学好速写先了解这几步
  19. thymeleaf th:value 多个值拼接 使用+号(不适用于th:field)
  20. 惠普打印机驱动安装教程,怎么安装打印机驱动

热门文章

  1. ChatGPT神奇应用:无需美术功底快速生成高清艺术插图
  2. 【学术相关】博士生学历真的很重要吗?
  3. 小项目:单片机控制脉搏心电测量仪 测量脉搏心跳 含程序 原理图及仿真文件
  4. Windows命令--ipconfig--使用/详解
  5. [机器学习]P问题、NP问题、NP完全问题和NP难问题
  6. 计算机组成原理——(论述篇)四、计算机的诞生与发展
  7. GAN实战之Pytorch 使用CGAN生成指定MNIST手写数字
  8. 2020-11-01栈的顺序栈实现
  9. CFF 201312-2
  10. 林大学计算机科学与技术学院,车翔玖-吉林大学计算机科学与技术学院