版權(quán)聲明:本文為本人原創(chuàng)文章咧栗,未經(jīng)本人允許不得轉(zhuǎn)載。
不知不覺已經(jīng)到第五篇了,本篇結(jié)束居凶,這個(gè)項(xiàng)目目前要展現(xiàn)的UI界面布局就差不多了,下一篇開始就會(huì)開始講數(shù)據(jù)庫(kù)本地存儲(chǔ)和業(yè)務(wù)邏輯了藤抡。剩下查詢侠碧、統(tǒng)計(jì)等頁(yè)面等我學(xué)習(xí)做完再寫,現(xiàn)在我自己也不會(huì) 哈哈哈缠黍!
廢話少說(shuō)弄兜,直接開始今天的內(nèi)容,先看兩個(gè)圖:
以上就是今天要說(shuō)的內(nèi)容:
1.首頁(yè)添加tabbar,用于分別展示所有項(xiàng)目和未結(jié)款項(xiàng)目
2.完成首頁(yè)項(xiàng)目卡片點(diǎn)擊后的詳細(xì)信息查看
1替饿、先講首頁(yè)tabbar的實(shí)現(xiàn)
之前我的文章也有介紹這部分實(shí)現(xiàn)语泽,相對(duì)不難,我們正好再?gòu)?fù)習(xí)下视卢。
要實(shí)現(xiàn)頂部tabbar效果踱卵,那么他不是某個(gè)單獨(dú)控件就可以展現(xiàn)的,是由一些控件組合起來(lái)才能正常運(yùn)行据过,包括:TabController惋砂、TabBar、TabBarView蝶俱。
首先找到home_page.dart
文件班利,修改其內(nèi)容:
@override
Widget build(BuildContext context) {
//使用默認(rèn)的tab控制器來(lái)實(shí)現(xiàn)tab標(biāo)簽和展示內(nèi)容的聯(lián)動(dòng)
return new DefaultTabController(
//length代表一共有幾個(gè)tabbar
length: 2,
child: new Scaffold(
//標(biāo)題欄,包含一個(gè)標(biāo)題和一個(gè)圖標(biāo)按鈕
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('未結(jié)(${_diyProjects.length})'),
],
),
),
//TabBarView用于展示對(duì)應(yīng)tab標(biāo)簽下的內(nèi)容榨呆,通過(guò)默認(rèn)的tab控制器來(lái)實(shí)現(xiàn)對(duì)應(yīng)
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('這是未結(jié)頁(yè)面'),
)
],
),
以上代碼再原有基礎(chǔ)上進(jìn)行了三處改動(dòng)
1罗标、在AppBar的bottom屬性里增加TabBar控件,并添加兩個(gè)標(biāo)簽
2积蜻、body屬性原來(lái)的ListView.build控件外面套上TabBarView闯割,用于存放標(biāo)簽頁(yè)對(duì)應(yīng)的視圖內(nèi)容
3、在整個(gè)Scaffold外增加DefaultTabController竿拆,通過(guò)這個(gè)默認(rèn)的控制器實(shí)現(xiàn)標(biāo)簽和視圖的聯(lián)動(dòng)
標(biāo)簽可以包含名字和圖標(biāo)宙拉,我這里就沒有放圖標(biāo),我在后面添加了一個(gè)數(shù)字丙笋,代表這個(gè)標(biāo)簽下的數(shù)據(jù)量谢澈。大家可以試試添加圖標(biāo)看看效果。
2御板、實(shí)現(xiàn)首頁(yè)項(xiàng)目卡片點(diǎn)擊進(jìn)入相信相信查看頁(yè)面
開始做之前先分析頁(yè)面結(jié)構(gòu)锥忿,觀察上圖發(fā)現(xiàn)這個(gè)頁(yè)面基本包含以下控件:
1、可以跟隨滑動(dòng)的sliverAppbar
2怠肋、floatingActionButton
3敬鬓、用于項(xiàng)目信息展示的ListTile
首先我們?cè)趐ages下新建diy_item_info.dart
,在ui下新建diy_info_show.dart
兩個(gè)文件笙各,我們將在這兩個(gè)文件里實(shí)現(xiàn)點(diǎn)擊卡片查看詳細(xì)信息钉答。
首先編輯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,將滑動(dòng)視圖和浮動(dòng)按鈕組合起來(lái)杈抢,實(shí)現(xiàn)按鈕附加在FlexibleSpaceBar效果
return new Stack(children: <Widget>[
//SliverAppBar需要配合CustomScrollView來(lái)實(shí)現(xiàn)
new CustomScrollView(
slivers: <Widget>[
new SliverAppBar(
//展開的高度
expandedHeight: 218.0,
//是否隨著滑動(dòng)消失
pinned: true,
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.content_paste),
onPressed: () {},
)
],
//展開的空間區(qū)域
flexibleSpace: new FlexibleSpaceBar(
//設(shè)置區(qū)域背景圖片
background: new Image.asset(
diyItem.imagePath,
fit: BoxFit.cover,
),
title: new Text(
'利潤(rùn):${diyItem.profit.toString()}',
style: new TextStyle(fontSize: 16.0),
),
centerTitle: true,
),
),
//sliverAppBar下面的內(nèi)容區(qū)域
new SliverList(
delegate: new SliverChildListDelegate([
//名稱和聯(lián)系人
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,
),
//活動(dòng)地點(diǎn)時(shí)間
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,
),
//活動(dòng)單價(jià)和份數(shù)
new ListTile(
leading: new Icon(
Icons.repeat,
color: Theme.of(context).primaryColor,
),
title: new Text('單價(jià): ${diyItem.singlePrcie}元'),
subtitle: new Text('份數(shù): ${diyItem.nums}'),
),
//活動(dòng)總價(jià)数尿、物料人員成本
new ListTile(
leading: new Icon(
Icons.attach_money,
color: Theme.of(context).primaryColor,
),
title: new Text('總價(jià): ${diyItem.totalAmount}元'),
subtitle: new Row(children: <Widget>[
new Text('物料: ${diyItem.itemCost}元'),
new SizedBox(
width: 10.0,
),
new Text('人員: ${diyItem.laborCost}元'),
]),
),
]),
)
],
),
//位置控件,用于擺放浮動(dòng)按鈕
new Positioned(
top: 218.0,
right: 26.0,
child: new FloatingActionButton(
backgroundColor: diyItem.isCheckOut ? Colors.green : Colors.redAccent,
onPressed: () {},
child: new Text(
diyItem.isCheckOut ? '已結(jié)清' : '未結(jié)清',
style: new TextStyle(fontSize: 12.0),
),
),
)
]);
}
}
以上代碼整體實(shí)現(xiàn)思路如下:
1惶楼、通過(guò)SliverAppBar和CustomScrollView結(jié)合實(shí)現(xiàn)可擴(kuò)展收縮的滑動(dòng)標(biāo)題欄
2砌创、通過(guò)ListTile完成項(xiàng)目信息的展示虏缸,中間通過(guò)Divider添加分割線。
3嫩实、通過(guò)Stack疊加控件和Positioned位置控件將FloatingActionButton放在SliverAppBar上刽辙。
由于我底下展示區(qū)域內(nèi)容不多,所以無(wú)法看到標(biāo)題欄的收縮效果甲献,如果多放幾個(gè)內(nèi)容滾動(dòng)的時(shí)候就會(huì)有收縮效果宰缤。
當(dāng)然了埋了一個(gè)坑在里面,不知道你是不是看出來(lái)了呢晃洒,可以試試如何解決這個(gè)問題慨灭,這個(gè)坑就下次再填吧 。
寫完UI布局球及,我們還需要編輯diy_item_info.dart文件氧骤,來(lái)展示以上的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,),
);
}
}
現(xiàn)在為止真是萬(wàn)事俱備,只欠路由咯吃引,因?yàn)槲覀冞€要去首頁(yè)card的點(diǎn)擊事件去配置導(dǎo)航路由到這個(gè)項(xiàng)目信息頁(yè)面
diy_list_show.dart
@override
Widget build(BuildContext context) {
//將整個(gè)項(xiàng)目展示內(nèi)容包裹在card里
return new Card(
margin: const EdgeInsets.fromLTRB(18.0, 18.0, 18.0, 9.0), //設(shè)置外邊距18
//card形狀設(shè)置頂部圓形弧度12筹陵,底部沒有
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(12.0))),
//inkwell是一個(gè)帶水波紋觸摸效果的控件,預(yù)留點(diǎn)擊回調(diào)作為以后點(diǎn)擊響應(yīng)事件
child: new InkWell(
onTap: () {
Navigator.of(context)
.push(new MaterialPageRoute(builder: (BuildContext context) {
return new DiyItemInfo(
diyItem: widget.diyItem,
);
}));
},
child: _diyContentShow(),
),
);
}
這樣我們就可以通過(guò)點(diǎn)擊首頁(yè)項(xiàng)目卡片查看項(xiàng)目信息咯镊尺。
最后
今天結(jié)束后朦佩,這個(gè)項(xiàng)目的UI布局除了查詢和統(tǒng)計(jì)頁(yè)面外基本就完成了。細(xì)心的你可能發(fā)現(xiàn)了目前的數(shù)據(jù)都是預(yù)設(shè)的庐氮,如何通過(guò)用戶添加语稠,如果進(jìn)行數(shù)據(jù)保存是必不可少的,所以下篇開始我將介紹Flutter本地?cái)?shù)據(jù)庫(kù)sqflite的用法以及業(yè)務(wù)交互邏輯弄砍。
最后附上項(xiàng)目源碼地址:https://gitee.com/xusujun33/activity_record_jia.git
項(xiàng)目持續(xù)更新中.......