Flutter新人实战—从0开始开发一个DIY活动记录应用(五)更多控件使用

版权声明:本文为本人原创文章,未经本人允许不得转载。

不知不觉已经到第五篇了,本篇结束,这个项目目前要展现的UI界面布局就差不多了,下一篇开始就会开始讲数据库本地存储和业务逻辑了。剩下查询、统计等页面等我学习做完再写,现在我自己也不会 哈哈哈!

废话少说,直接开始今天的内容,先看两个图:


image.png

image.png

image.png

以上就是今天要说的内容:

1.首页添加tabbar,用于分别展示所有项目和未结款项目
2.完成首页项目卡片点击后的详细信息查看

1、先讲首页tabbar的实现

之前我的文章也有介绍这部分实现,相对不难,我们正好再复习下。
要实现顶部tabbar效果,那么他不是某个单独控件就可以展现的,是由一些控件组合起来才能正常运行,包括:TabController、TabBar、TabBarView。
首先找到home_page.dart文件,修改其内容:

@override
  Widget build(BuildContext context) {
    //使用默认的tab控制器来实现tab标签和展示内容的联动
    return new DefaultTabController(
      //length代表一共有几个tabbar
      length: 2,
      child: new Scaffold(
        //标题栏,包含一个标题和一个图标按钮
        appBar: new AppBar(
          title: new Text(_title),
          actions: <Widget>[
            new IconButton(icon: new Icon(Icons.palette), onPressed: () {})
          ],
          //TabBar是属于appbar的底部属性控件
          bottom: new TabBar(
            indicatorColor: Colors.white,
            indicatorSize: TabBarIndicatorSize.label,
            tabs: <Widget>[
              new Text('全部(${_diyProjects.length})'),
              new Text('未结(${_diyProjects.length})'),
            ],
          ),
        ),
        //TabBarView用于展示对应tab标签下的内容,通过默认的tab控制器来实现对应
        body: new TabBarView(
          children: <Widget>[
            new ListView.builder(
              itemCount: _diyProjects.length,
              itemBuilder: (context, index) {
                return new DiyListShow(
                  diyItem: _diyProjects[index],
                );
              },
            ),
            new Center(
              child: new Text('这是未结页面'),
            )
          ],
        ),

以上代码再原有基础上进行了三处改动

1、在AppBar的bottom属性里增加TabBar控件,并添加两个标签
2、body属性原来的ListView.build控件外面套上TabBarView,用于存放标签页对应的视图内容
3、在整个Scaffold外增加DefaultTabController,通过这个默认的控制器实现标签和视图的联动

标签可以包含名字和图标,我这里就没有放图标,我在后面添加了一个数字,代表这个标签下的数据量。大家可以试试添加图标看看效果。

2、实现首页项目卡片点击进入相信相信查看页面

开始做之前先分析页面结构,观察上图发现这个页面基本包含以下控件:

1、可以跟随滑动的sliverAppbar
2、floatingActionButton
3、用于项目信息展示的ListTile

首先我们在pages下新建diy_item_info.dart,在ui下新建diy_info_show.dart两个文件,我们将在这两个文件里实现点击卡片查看详细信息。
首先编辑diy_info_show.dart:

import 'package:activity_record/model/diy_project.dart';
import 'package:flutter/material.dart';

class DiyInfoShow extends StatelessWidget {
  DiyInfoShow({Key key, this.diyItem}) : super(key: key);
  DiyProject diyItem;

@override
  Widget build(BuildContext context) {
    //使用stack,将滑动视图和浮动按钮组合起来,实现按钮附加在FlexibleSpaceBar效果
    return new Stack(children: <Widget>[
      //SliverAppBar需要配合CustomScrollView来实现
      new CustomScrollView(
        slivers: <Widget>[
          new SliverAppBar(
            //展开的高度
            expandedHeight: 218.0,
            //是否随着滑动消失
            pinned: true,
            actions: <Widget>[
              new IconButton(
                icon: new Icon(Icons.content_paste),
                onPressed: () {},
              )
            ],
            //展开的空间区域
            flexibleSpace: new FlexibleSpaceBar(
              //设置区域背景图片
              background: new Image.asset(
                diyItem.imagePath,
                fit: BoxFit.cover,
              ),
              title: new Text(
                '利润:${diyItem.profit.toString()}',
                style: new TextStyle(fontSize: 16.0),
              ),
              centerTitle: true,
            ),
          ),
          //sliverAppBar下面的内容区域
          new SliverList(
            delegate: new SliverChildListDelegate([
              //名称和联系人
              new ListTile(
                leading: new Icon(
                  Icons.toys,
                  color: Theme.of(context).primaryColor,
                ),
                title: new Text(diyItem.name,
                    style: new TextStyle(
                        fontWeight: FontWeight.bold, fontSize: 22.0)),
                subtitle: new Text(diyItem.contact),
              ),
              new Divider(
                indent: 16.0,
              ),
              //活动地点时间
              new ListTile(
                leading: new Icon(
                  Icons.open_with,
                  color: Theme.of(context).primaryColor,
                ),
                title: new Text(diyItem.place,
                    style: new TextStyle(fontWeight: FontWeight.w500)),
                subtitle: new Text(diyItem.date),
              ),
              new Divider(
                indent: 16.0,
              ),
              //活动单价和份数
              new ListTile(
                leading: new Icon(
                  Icons.repeat,
                  color: Theme.of(context).primaryColor,
                ),
                title: new Text('单价: ${diyItem.singlePrcie}元'),
                subtitle: new Text('份数: ${diyItem.nums}'),
              ),
              //活动总价、物料人员成本
              new ListTile(
                leading: new Icon(
                  Icons.attach_money,
                  color: Theme.of(context).primaryColor,
                ),
                title: new Text('总价: ${diyItem.totalAmount}元'),
                subtitle: new Row(children: <Widget>[
                  new Text('物料: ${diyItem.itemCost}元'),
                  new SizedBox(
                    width: 10.0,
                  ),
                  new Text('人员: ${diyItem.laborCost}元'),
                ]),
              ),
            ]),
          )
        ],
      ),
      //位置控件,用于摆放浮动按钮
      new Positioned(
        top: 218.0,
        right: 26.0,
        child: new FloatingActionButton(
          backgroundColor: diyItem.isCheckOut ? Colors.green : Colors.redAccent,
          onPressed: () {},
          child: new Text(
            diyItem.isCheckOut ? '已结清' : '未结清',
            style: new TextStyle(fontSize: 12.0),
          ),
        ),
      )
    ]);
  }
}

以上代码整体实现思路如下:

1、通过SliverAppBar和CustomScrollView结合实现可扩展收缩的滑动标题栏
2、通过ListTile完成项目信息的展示,中间通过Divider添加分割线。
3、通过Stack叠加控件和Positioned位置控件将FloatingActionButton放在SliverAppBar上。

由于我底下展示区域内容不多,所以无法看到标题栏的收缩效果,如果多放几个内容滚动的时候就会有收缩效果。
当然了埋了一个坑在里面,不知道你是不是看出来了呢,可以试试如何解决这个问题,这个坑就下次再填吧 。

写完UI布局,我们还需要编辑diy_item_info.dart文件,来展示以上的UI代码:
diy_item_info.dart

import 'package:activity_record/model/diy_project.dart';
import 'package:activity_record/ui/diy_info_show.dart';
import 'package:flutter/material.dart';

class DiyItemInfo extends StatelessWidget {
  DiyItemInfo({Key key, this.diyItem}) : super(key: key);
  DiyProject diyItem;

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: new DiyInfoShow(diyItem: diyItem,),
    );
  }
}

现在为止真是万事俱备,只欠路由咯,因为我们还要去首页card的点击事件去配置导航路由到这个项目信息页面
diy_list_show.dart

@override
  Widget build(BuildContext context) {
    //将整个项目展示内容包裹在card里
    return new Card(
      margin: const EdgeInsets.fromLTRB(18.0, 18.0, 18.0, 9.0), //设置外边距18
      //card形状设置顶部圆形弧度12,底部没有
      shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.vertical(top: Radius.circular(12.0))),
      //inkwell是一个带水波纹触摸效果的控件,预留点击回调作为以后点击响应事件
      child: new InkWell(
        onTap: () {
          Navigator.of(context)
              .push(new MaterialPageRoute(builder: (BuildContext context) {
            return new DiyItemInfo(
              diyItem: widget.diyItem,
            );
          }));
        },
        child: _diyContentShow(),
      ),
    );
  }

这样我们就可以通过点击首页项目卡片查看项目信息咯。

最后

今天结束后,这个项目的UI布局除了查询和统计页面外基本就完成了。细心的你可能发现了目前的数据都是预设的,如何通过用户添加,如果进行数据保存是必不可少的,所以下篇开始我将介绍Flutter本地数据库sqflite的用法以及业务交互逻辑。

最后附上项目源码地址:https://gitee.com/xusujun33/activity_record_jia.git
项目持续更新中.......

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容