专栏首页三流程序员的挣扎Flutter 学习笔记4-构建布局示例

Flutter 学习笔记4-构建布局示例

要做出这样一个页面

15456449998868.jpg

设置

  • 在工程根目录创建 images 文件夹
  • 将图片 lake.jpg 复制到文件夹
  • 更新 pubspec.yaml 文件以包含 assets 标签,使图片在代码中可用 # To add assets to your application, add an assets section, like this: assets: - images/lake.jpg # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg

分析布局

15456452015079.png

首先是一列,有四个子元素,每个占据一行。第一行就是一张图,第二行称为标题行。

15456452958049.png

一行中有三个子元素,其中第一列子元素本身又是一列,包含两行文字。需要占用大量空间,所以它必须包装在 Expanded widget 中。

第三行有三列按钮,一个纵向的图标和文字。

15456454982907.png

构建布局

首先写好基本的结构,build 方法先空实现。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO
  }
}

下面的代码都是在 build 方法内部编写。

实现标题行

标题行有三列,其中第一列要拉伸以使用该行的所有剩余空间。在 Expand 中添加一个列。

Widget titleSection = Container( // 标题行一个 Container
  padding: const EdgeInsets.all(32.0), // 四周的 32 像素的内边距
  child: Row( // 内部是一行,只有一个 child
    children: [ // 一行中有多个 child,用 children,是个数组
      Expanded( // 第一列要撑满
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start, // 撑满时内部左对齐
          children: [ // 一列有两行
            Container( // 有 padding,又用了个 Container
              padding: const EdgeInsets.only(bottom: 8.0), // 底部有 8 个像素
              child: Text( // 第一行文字
                'Oeschinen Lake Campground',
                style: TextStyle(
                  fontWeight: FontWeight.bold,
                ),
              ),
            ),
            Text( // 没有 padding,直接一个 Text
              'Kandersteg, Switzerland',
              style: TextStyle(
                color: Colors.grey[500],
              ),
            ),
          ],
        ),
      ),
      Icon( // 第二列一个图标
        Icons.star,
        color: Colors.red[500],
      ),
      Text('41'), // 第三列是文字
    ],
  ),
);

实现按钮行

有三列,每列两行,其中颜色用主题中的 primary color,所以先定义主题 Theme。

return MaterialApp(
  title: 'Flutter Demo',
  theme: ThemeData(
    primarySwatch: Colors.blue,
  ),
);

由于构建每列几乎相同,所以在 build 方法内部写一个函数,用于构建一列。

Column buildButtonColumn(IconData icon, String label) {
  Color color = Theme.of(context).primaryColor;

  return Column(
    mainAxisSize: MainAxisSize.min,
    mainAxisAlignment: MainAxisAlignment.center,
    children: [
      Icon(icon, color: color), // 一个图标
      Container( // 有这种边距的,感觉都类似 CSS 的盒模型,用个 Container 包起来
        margin: const EdgeInsets.only(top: 8.0), // 上边距 8 像素
        child: Text(
          label,
          style: TextStyle(
            fontSize: 12.0,
            fontWeight: FontWeight.w400,
            color: color,
          ),
        ),
      ),
    ],
  );
}

然后用这个函数来创建三个列。

Widget buttonSection = Container(
  child: Row( // 一行
    mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 行内每列平均分配剩余空间
    children: [
      buildButtonColumn(Icons.call, 'CALL'),
      buildButtonColumn(Icons.near_me, 'ROUTE'),
      buildButtonColumn(Icons.share, 'SHARE'),
    ],
  ),
);

实现文本部分

Widget textSection = Container(
  padding: const EdgeInsets.all(32.0), // 四周有内边距
  child: 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.
    ''',
    softWrap: true, // 自动换行
  ),
);

实现图片和整合

将图片和上述所有放入一个 ListView 中,以便在小设备上可以自动滚动。

return MaterialApp(
  title: 'Flutter Demo',
  theme: ThemeData(
    primarySwatch: Colors.blue,
  ),
  home: Scaffold(
    appBar: AppBar(
      title: Text('Top Lakes'),
    ),
    body: ListView(
      children: [
        Image.asset(
          'images/lake.jpg', // 使用这个图片
          width: 600.0,
          height: 240.0,
          fit: BoxFit.cover, // 图片在覆盖整个渲染框的同时尽可能小
        ),
        titleSection,
        buttonSection,
        textSection,
      ],
    ),
  ),
);

按示例代码写,按钮行没有显示出来,结果发现是 Theme.of(context).primaryColor 没有值,跟 Theme 里的 primarySwatch: Colors.blue 没有关系。所以先将 buildButtonColumn 方法里的 color 改成 Colors.blue,然后正常显示了。

device-2018-12-28-214346.png

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Android 透明状态栏(伪沉浸式)

    而由于 Android API 的不同,需要考虑 4.4、5.0、6.0 前后的不同。

    七适散人
  • Flutter 学习笔记6 - 常用 Widgets

    下面的 widget 分为两类:widgets library中的标准 widget 和 Material Components library 中的专用 wi...

    七适散人
  • Flutter 学习笔记 15 - 动画 AnimatedBuilder

    之前的例子,build 中使用 Animation 的 value 作为 logo 的宽高,更好的解决方案是将职责分离,logo 的显示只做显示,尺寸的变化应该...

    七适散人
  • 微信小程序的自动化测试框架

    官方地址如下:https://git.weixin.qq.com/minitest/minium-doc/tree/master

    Criss@陈磊
  • 微信小程序的自动化测试框架

    官方地址如下:https://git.weixin.qq.com/minitest/minium-doc/tree/master

    Criss@陈磊
  • win10 安装flutter记录

    2、配置环境变量,这里我本来想试试配成本地位置,结果到后来运行时候跑不起来,无奈最后还是按官网的来,当前用户新增PUB_HOSTED_URL和FLUTTER_S...

    吴裕超
  • android studio一个module依赖另外一个module

    出现的问题:Dependency:unspecified on project app resolves to an APK archive which is ...

  • 组合优化问题Talent Scheduling Problem(TSP)简介

    今天为大家介绍的问题是Talent Scheduling Problem,因为没有合适的中文翻译,所以下面直接简称其为TSP (注意, 这里的TSP可不是旅行商...

    用户1621951
  • Programming Assignment 2 Seam Carving 暴力实现

    felix
  • 【leetcode刷题】T206-范围求和 II

    https://leetcode-cn.com/problems/range-addition-ii

    木又AI帮

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动