在上一節(jié)中,我們開發(fā)了主界面框架,主體結(jié)構(gòu)是底部為TabBar,分別對應(yīng)5個(gè)頁面:日程、患 者、消息、醫(yī)院、我的。在這一節(jié)中,我們將以日程頁面為例,介紹列表控件的使用。
功能需求
在日程頁面中將顯示醫(yī)生的日程安排,包括:坐診、執(zhí)班、預(yù)約、隨訪、出診、家訪。下面分別來進(jìn)行介紹:
- 坐診
坐診指醫(yī)生在醫(yī)院出診情況,需記錄如下信息:醫(yī)院、科室、級別、開始時(shí)間、結(jié)束時(shí)間,與HIS系統(tǒng)打通后,可以看到就診患者列表,以及患者的病歷。 - 執(zhí)班
執(zhí)班是指醫(yī)生在醫(yī)院工作但是不出診情況。 - 預(yù)約
預(yù)約是指患者主動(dòng)向醫(yī)生發(fā)起預(yù)約,由醫(yī)生同意后,形成的預(yù)約,包括:就診醫(yī)院、就診科室、就診時(shí)間(以半小時(shí)為限),患者在預(yù)約時(shí)可以通過圖文及聲音形式描述自己的病情,醫(yī)生可以根據(jù)患者自述決定是否接受預(yù)約。 - 隨訪
醫(yī)生在醫(yī)院通過電話、短信或圖文信息形式,詢問患者病情、康復(fù)情況和醫(yī)囑遵從情況。 - 出診
醫(yī)生主動(dòng)到患者家中進(jìn)行診療活動(dòng)的計(jì)劃安排,包括:時(shí)間、地點(diǎn)、患者,醫(yī)生可以在出診現(xiàn)場查看患者病歷,提出建議,并開具處方藥品,這部分功能需要與HIS打通。 - 家醫(yī)
醫(yī)護(hù)人員到患者家中進(jìn)行醫(yī)療活動(dòng)的服務(wù),如輸液、換藥等。
這六種情況統(tǒng)一在列表中顯示,醫(yī)生可以選擇只看其中的一種,還可以按照時(shí)間和類別進(jìn)行查詢,每個(gè)類別均有相應(yīng)的詳細(xì)信息頁面,有些頁面還可以查看患者的詳細(xì)信息,進(jìn)一步查看患者的病歷。
基本功能介紹完之后,下面我們來看如何用Flutter實(shí)現(xiàn)這一功能。
列表功能實(shí)現(xiàn)
我們把項(xiàng)目中所有的界面中組件,放在components目錄下,所以我們需要在項(xiàng)目的lib文件夾下,新建一個(gè)components文件夾。
我們第一期先顯示出診和預(yù)約兩種日程條目,我們首先定義一個(gè)日程列表?xiàng)l目的基類ScheduleListItem,該類只相當(dāng)于一個(gè)接口,所以定義為抽象類,如下所示:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
abstract class ScheduleListItem {}
我們接著來定義出診日程條目,該條目需要記錄時(shí)間、地點(diǎn)和患者等信息,如下所示:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:szys/components/ScheduleListItem.dart';
class OnsiteScheduleListItem implements ScheduleListItem {
final scheduleId;
final String planTime;
final String planAddr;
final int patientId;
final String patientName;
OnsiteScheduleListItem(this.scheduleId, this.planTime, this.planAddr,
this.patientId, this.patientName);
}
接下來我們定義預(yù)約條目,該條目需要記錄出診醫(yī)院、科室、時(shí)間、預(yù)約狀態(tài)、患者等信息,如下所示:
class AppointScheduleListItem implements ScheduleListItem {
final int scheduleId;
final int hospitalId;
final String hospitalName;
final int deptId;
final String deptName;
final int appointId;
final String appointTime;
final int appointStateId;
final String appointStateName;
final int patientId;
final String patientName;
AppointScheduleListItem(this.scheduleId, this.hospitalId,
this.hospitalName, this.deptId, this.deptName,
this.appointId, this.appointTime, this.appointStateId,
this.appointStateName, this.patientId, this.patientName);
}
我們定義日程的ListView類ScheduleListView,代碼如下所示:
import 'package:flutter/material.dart';
import 'package:szys/components/ScheduleListItem.dart';
import 'package:szys/components/OnsiteScheduleListItem.dart';
import 'package:szys/components/AppointScheduleListItem.dart';
class ScheduleListView extends StatefulWidget {
@override
ScheduleListViewState createState() => new ScheduleListViewState();
}
class ScheduleListViewState extends State<ScheduleListView> {
@override
Widget build(BuildContext context) {
List<ScheduleListItem> items = getScheduleListItems(1001);
return new ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
if (item is OnsiteScheduleListItem) {
return buildOnsiteListTile(item);
} else if (item is AppointScheduleListItem) {
return buildAppointListItem(item);
} else {
return new ListTile(
isThreeLine: true,//子item的是否為三行
dense: false,
leading: new CircleAvatar(child: new Text('未知'),),//左側(cè)首字母圖標(biāo)顯示,不顯示則傳null
title: new Text('未知標(biāo)題'),//子item的標(biāo)題
subtitle: new Text('未知內(nèi)容'),//子item的內(nèi)容
trailing: new Icon(Icons.arrow_right,color: Colors.lightBlue,),//顯示右側(cè)的箭頭,不顯示則傳null
);
}
},
);
}
......
}
這里面最重要的就是build方法,由該方法產(chǎn)生界面中可顯示的內(nèi)容。在一開始,我們根據(jù)醫(yī)生的編號獲取醫(yī)生的日程列表,getScheduleListItems函數(shù)是用程序?qū)懰赖牧斜頂?shù)據(jù),還沒有從服務(wù)器上取。
接著我們調(diào)用listView.builder方法,在其中的itemBuilder中,我們遍歷列表?xiàng)l目,對于每個(gè)條目我們判斷其類型,如果是出診類型,則由buildOnsiteScheduleListItem來生成對應(yīng)的列表?xiàng)l目,如果是預(yù)約類型,則由buildAppointScheduleListItem來生成對應(yīng)的列表?xiàng)l目,如果都不是,則顯示未知類型條目。
接下來我們來看生成測試條目的函數(shù)實(shí)現(xiàn):
List<ScheduleListItem> getScheduleListItems(int doctorId) {
List<ScheduleListItem> items = new List<ScheduleListItem>();
ScheduleListItem item = new OnsiteScheduleListItem(1,
'2018-07-28 10:00:00', '中關(guān)村雙榆樹小區(qū)6#305',
101, '張新中');
items.add(item);
//
item = new OnsiteScheduleListItem(2,
'2018-07-28 10:30:00', '中關(guān)村雙榆樹小區(qū)8#205',
102, '王水');
items.add(item);
......
return items;
}
接下來我們看出診日程列表?xiàng)l目的生成:
Widget buildOnsiteListTile(OnsiteScheduleListItem item) {
return new ListTile(
isThreeLine: true,//子item的是否為三行
dense: false,
leading: new CircleAvatar(child: new Text('出診'),),//左側(cè)首字母圖標(biāo)顯示,不顯示則傳null
title: new Text('出診患者:' + item.patientName),//子item的標(biāo)題
subtitle: new Text('時(shí)間:' + item.planTime +
'\r\n地址:' + item.planAddr),//子item的內(nèi)容
trailing: new Icon(Icons.arrow_right,color: Colors.lightBlue,),//顯示右側(cè)的箭頭,不顯示則傳null
);
}
我們再來看預(yù)約列表?xiàng)l目生成:
Widget buildAppointListItem(AppointScheduleListItem item) {
return new ListTile(
isThreeLine: true,//子item的是否為三行
dense: false,
leading: new CircleAvatar(child: new Text('預(yù)約'),),//左側(cè)首字母圖標(biāo)顯示,不顯示則傳null
title: new Text('' + item.hospitalName + item.deptName),//子item的標(biāo)題
subtitle: new Text('時(shí)間:' + item.appointTime +
'\r\n狀態(tài):' + item.appointStateName +
'\r\n患者:' + item.patientName),//子item的內(nèi)容
trailing: new Icon(Icons.arrow_right,color: Colors.lightBlue,),//顯示右側(cè)的箭頭,不顯示則傳null
);
}
我們把日程列表內(nèi)容的生成和顯示已經(jīng)做好了,接下來我們將其加入我們的日程頁面,打開SchedulePage類,將其中的center替換為ScheduleListView
import 'package:szys/components/ScheduleListView.dart';
......
class SchedulePageState extends State<SchedulePage> {
@override
Widget build(BuildContext context) {
//items.add(value);
return new Scaffold(
appBar: new AppBar(
title: new Text('日程管理')
),
body: new Center(
child: new ScheduleListView()
)
);
}
}
我們保存上述修改,直接到手機(jī)上來查看,我們將看到一個(gè)如下所示的列表頁面:

在這一節(jié)中,我們實(shí)現(xiàn)了一個(gè)最簡單的列表頁面,當(dāng)然還沒有加下拉刷新和上拉加載更多的功能,我們準(zhǔn)備在下一個(gè)版本中再添加相應(yīng)的功能。
在這里我們的列表內(nèi)容還是靜態(tài)的,在下一節(jié)中,我們將從網(wǎng)絡(luò)獲取數(shù)據(jù)并顯示到界面中,靜請期待。