[譯]Building WhatsApp Ui with Flutter Part 2 : The Chat List

在使用Flutter構(gòu)建WhatsApp之前杰赛,我們創(chuàng)建了一個(gè)帶有選項(xiàng)卡和導(dǎo)航的基本appbar另患。 今天捆等,我們將使用ListView.builder創(chuàng)建聊天的滾動(dòng)列表

隨著介紹降铸,這里是我們將要構(gòu)建的截圖


#設(shè)置模型

在我們構(gòu)建List之前住拭,我們將為聊天構(gòu)建模板潭袱。 我們首先在lib文件夾中創(chuàng)建一個(gè)名為“model”的新文件夾柱嫌。 在模型文件夾中,創(chuàng)建名為chat_model.dart的文件屯换。 創(chuàng)建文件后编丘,我們現(xiàn)在可以開(kāi)始構(gòu)建結(jié)構(gòu)了。 我們將從創(chuàng)建ChatModel類開(kāi)始彤悔。

class ChatModel {

}

在這個(gè)類中嘉抓,我們將為我們想要聊天列表的功能創(chuàng)建變量。 WhatsApp通常具有消息的人物晕窑,姓名抑片,時(shí)間和消息的片段。

創(chuàng)建不同的變量杨赤,將它們分配給類型字符串敞斋。 它們被設(shè)置為final截汪,因?yàn)槲覀冎辉O(shè)置一次值。 如果您想了解有關(guān)dart中不同變量類型的更多信息渺尘,請(qǐng)查看dart變量介紹視頻

class ChatModel {

? final String username;

? final String message;?

? final String time;

? final String avatarurl;

}

很好挫鸽,聲明了變量,我們現(xiàn)在可以將它傳遞給類的構(gòu)造函數(shù)

這是通過(guò)以下代碼行完成的

ChatModel({this.username, this.message, this.time, this.avatarurl});

接下來(lái)鸥跟,我們繼續(xù)創(chuàng)建一個(gè)聊天列表丢郊。 為此,我們創(chuàng)建一個(gè)名為data的變量医咨,它將是List類型枫匾。 該列表將是ChatModel類型。 這可確保輸入的數(shù)據(jù)遵循類中列出的格式拟淮。

```

List data = [

?new ChatModel(

?? username: 'Nash',

?? message: 'Flutter is soooo cool :)',

?? time: '20:20',

? avatarurl: 'https://pbs.twimg.com/profile_images/945767488087715840/OP_ZIptm_400x400.jpg'

?),

?new ChatModel(

?? username: 'Han Solo',

?? message: 'That is not how the force works ',

? time: '20:20',

? avatarurl: 'https://pbs.twimg.com/profile_images/760249570085314560/yCrkrbl3_400x400.jpg'?

?),

? new ChatModel(

?? username: 'Ethan',

?? message: 'why hello there',

? time: '20:20',

? avatarurl: 'https://s-media-cache-ak0.pinimg.com/originals/d4/c3/ee/d4c3ee93cca0bba877318989b46b39d6.jpg'

?),

? new ChatModel(

?? username: 'Sam',

?? message: 'Lorem ipsum delor sit amet...',

? time: '20:20',

? avatarurl: 'http://clipart-library.com/images/kTMKzGyMc.jpg'

?),

? new ChatModel(

?? username: 'Ava',

?? message: 'AOT is better than JIT ;)',

? time: '20:20',

? avatarurl: 'http://clipart-library.com/images/kTMKzGyMc.jpg'

?),

? new ChatModel(

?? username: 'Jbird',

?? message: 'Stop camping in fortnite Idiot',

? time: '20:20',

? avatarurl: 'https://s-media-cache-ak0.pinimg.com/originals/d4/c3/ee/d4c3ee93cca0bba877318989b46b39d6.jpg'

?),

?? new ChatModel(

?? username: 'Jake',

?? message: 'Flutter is the best!',

? time: '20:20',

? avatarurl: 'http://clipart-library.com/images/kTMKzGyMc.jpg'

?),] ;

```

在上面的代碼中干茉,我們創(chuàng)建了七個(gè)帶有消息的用戶。 每個(gè)模型都遵循我們創(chuàng)建的格式很泊。 您可以編輯此項(xiàng)以包含任意數(shù)量的用戶角虫。 使用創(chuàng)建聊天的模板,我們現(xiàn)在可以移動(dòng)到實(shí)際列表視圖委造。

列表視圖

首先戳鹅,我們打開(kāi)chat_screen.dart并導(dǎo)入剛剛創(chuàng)建的文件。

`import '../model/chat_model.dart';

`

接下來(lái)昏兆,我們將小部件從Stateless更改為Stateful

```

class ChatScreen extends StatelessWidget {

? @override

? Widget build(BuildContext context){

? ? return new Container(

? ? ? child: new Center(

? ? ? ? child: new Text('Hello from Chat Screen ', style: new TextStyle(fontSize: 20.0),),

? ? ? )

? ? );

? }

}

```

```

class ChatScreen extends StatefulWidget {

? _ChatScreen createState() => new _ChatScreen();

}

class _ChatScreen extends State {

? @override

? Widget build(BuildContext context) {

? ? return new Container();

? }

}

```

是時(shí)候去玩有趣的東西枫虏,用ListView.builder替換Container。 ListView允許我們?cè)谄聊簧巷@示滾動(dòng)的小部件數(shù)組爬虱。 它有許多不同的屬性隶债,但我們將要使用的是itemCount和itemBuilder。 itemCount不應(yīng)等于零跑筝。 itemBuilder用于構(gòu)建列表的項(xiàng)目死讹。 它需要一種與Stateful和Stateless小部件非常相似的構(gòu)建方法。 主要區(qū)別在于添加索引變量继蜡。

Stateless/Stateful

`(BuildContext context)`

itemBuilder

`(BuildContext context, int index)

`

修改ChatScreen

```

class ChatScreen extends StatefulWidget {

? _ChatScreen createState() => new _ChatScreen();

}

class _ChatScreen extends State {

? @override

? Widget build(BuildContext context) {

? ? return new Container();

? }

}

```

To

```

class ChatScreen extends StatefulWidget {

? _ChatScreen createState() => new _ChatScreen();

}

class _ChatScreen extends State {

? @override

? Widget build(BuildContext context) {

? ? return new ListView.builder(

? ? ? itemCount:?

?? ? ? itemBuilder: (BuildContext context, int index) {}

? ? );

? }

}

```

對(duì)于我們的itemCount回俐,我們將使用之前創(chuàng)建的數(shù)據(jù)列表的長(zhǎng)度。 只需data.length的值

接下來(lái)稀并,我們將處理聊天項(xiàng)目仅颇。 在itemBuilder中,創(chuàng)建一個(gè)新列碘举。 該列是一個(gè)小部件忘瓦,它在垂直數(shù)組中顯示其子節(jié)點(diǎn)。

? 正如您在WhatsApp中所注意到的那樣,每條聊天都有一條細(xì)細(xì)的灰色線條耕皮。 要鏡像此效果境蜕,我們使用Divider小部件。 這個(gè)小部件允許我們用屏幕分隔屏幕上的元素凌停。 高度粱年,顏色和縮進(jìn)都可以改變,現(xiàn)在罚拟,我們只需要設(shè)置10.0的高度(數(shù)字必須是小數(shù)值)台诗。

? 創(chuàng)建Divider后,我們將移至ListTile赐俗。 這是另一個(gè)預(yù)制的Flutter小部件拉队,它易于使用但功能非常強(qiáng)大。 有不同的屬性阻逮,如leading, title 和 subtitle都'baked in'粱快。 在Divider下,我們通過(guò)鍵入新的ListTile()來(lái)創(chuàng)建小部件叔扼。

?您的_ChatScreen類應(yīng)如下所示


```

?class _ChatScreen extends State {

? @override

? Widget build(BuildContext context) {

? ? return new ListView.builder(

? ? ? itemCount: data.length,

? ? ? itemBuilder: (BuildContext context, int index) {

? ? ? ? return new Column(

? ? ? ? ? children: [

? ? ? ? ? ? new Divider(

? ? ? ? ? ? ? height: 10.0,

? ? ? ? ? ? ),

? ? ? ? ? ? new ListTile(

? ? ? ? ? ? ),

? ? ? ? ? ],

? ? ? ? );

? ? ? },

? ? );

? }

}

```

首先事哭,我們從Circle Avatar開(kāi)始。 這是消息左側(cè)的圖片瓜富,以用戶的圖片為特色慷蠕。 這在Flutter中創(chuàng)建非常簡(jiǎn)單。 在列表磁貼中食呻,我們將leading屬性設(shè)置為新的Circle頭像。 然后我們指定它的背景顏色和背景圖像澎现。 背景顏色可以是您喜歡的任何顏色仅胞,在此示例中我使用灰色。 對(duì)于背景圖像剑辫,我們使用網(wǎng)絡(luò)圖像干旧。 傳入我們數(shù)據(jù)列表中的頭像URL。使用以下代碼完成:

```

new ListTile(?

?leading: new CircleAvatar(

?backgroundColor: Colors.grey,?

?backgroundImage: new NetworkImage(data[index].avatarurl),?

?),

```

注意對(duì)于NetworkImage妹蔽,我們指定data [index]椎眯。 傳遞的索引來(lái)自itemBuilder中創(chuàng)建的索引。 對(duì)于每次迭代胳岂,索引都會(huì)改變编整。

創(chuàng)建我們的頭像后,我們會(huì)將注意力轉(zhuǎn)移到用戶名和時(shí)間/日期乳丰。 由于這兩個(gè)位于同一行掌测,我們可以使用Row小部件。 這與列非常相似产园,除了不是垂直對(duì)齊汞斧,小部件水平對(duì)齊夜郁。

```

title: new Row(

? ? mainAxisAlignment: MainAxisAlignment.spaceBetween,

? ? children: [

? ? ? new Text(data[index].username,

? ? ? ? ? style: new TextStyle(fontWeight: FontWeight.bold)),

? ? ? new Text(data[index].time,

? ? ? ? ? style: new TextStyle(color: Colors.grey, fontSize: 14.0))

? ? ],

? ),

```

同樣,我們使用數(shù)據(jù)列表中的信息粘勒,傳入索引竞端。 此外,我們使用Text小部件的style屬性來(lái)相應(yīng)地設(shè)置它們的樣式庙睡。

最后事富,消息片段。 為此埃撵,我們將使用subtitle屬性赵颅。 創(chuàng)建一個(gè)容器窗口小部件,它將在文本窗口小部件的頂部添加5.0填充暂刘,該窗口小部件將分配給其子窗口饺谬。 “文本”窗口小部件將顯示該用戶的數(shù)據(jù)列表中的消息。 索引再次傳入谣拣。文本的樣式也會(huì)更改募寨,以便增加字體大小和不同顏色。

您的文件現(xiàn)在應(yīng)該如下所示

```

import 'package:flutter/material.dart';

import '../model/chat_model.dart';

class ChatScreen extends StatefulWidget {

? _ChatScreen createState() => new _ChatScreen();

}

class _ChatScreen extends State {

? @override

? Widget build(BuildContext context) {

? ? return new ListView.builder(

? ? ? itemCount: data.length,

? ? ? itemBuilder: (BuildContext context, int index) {

? ? ? ? return new Column(

? ? ? ? ? children: [

? ? ? ? ? ? new Divider(

? ? ? ? ? ? ? height: 10.0,

? ? ? ? ? ? ),

? ? ? ? ? ? new ListTile(

? ? ? ? ? ? ? leading: new CircleAvatar(

? ? ? ? ? ? ? ? backgroundColor: Colors.grey,

? ? ? ? ? ? ? ? backgroundImage: new NetworkImage(data[index].avatarurl),

? ? ? ? ? ? ? ),

? ? ? ? ? ? ? title: new Row(

? ? ? ? ? ? ? ? mainAxisAlignment: MainAxisAlignment.spaceBetween,

? ? ? ? ? ? ? ? children: [

? ? ? ? ? ? ? ? ? new Text(data[index].username,

? ? ? ? ? ? ? ? ? ? ? style: new TextStyle(fontWeight: FontWeight.bold)),

? ? ? ? ? ? ? ? ? new Text(data[index].time,

? ? ? ? ? ? ? ? ? ? ? style: new TextStyle(color: Colors.grey, fontSize: 14.0))

? ? ? ? ? ? ? ? ],

? ? ? ? ? ? ? ),

? ? ? ? ? ? ? subtitle: new Container(

? ? ? ? ? ? ? ? ? padding: const EdgeInsets.only(top: 5.0),

? ? ? ? ? ? ? ? ? child: new Text(data[index].message,style: new TextStyle(color: Colors.grey, fontSize: 15.0) ), ),

? ? ? ? ? ? )

? ? ? ? ? ],

? ? ? ? );

? ? ? },

? ? );

? }

}

```

現(xiàn)在森缠,如果你重新加載你的應(yīng)用程序拔鹰,你應(yīng)該看到一個(gè)可操作的,可滾動(dòng)的聊天列表贵涵。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末列肢,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子宾茂,更是在濱河造成了極大的恐慌瓷马,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跨晴,死亡現(xiàn)場(chǎng)離奇詭異欧聘,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)端盆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門怀骤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人焕妙,你說(shuō)我怎么就攤上這事蒋伦。” “怎么了焚鹊?”我有些...
    開(kāi)封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵凉敲,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)爷抓,這世上最難降的妖魔是什么势决? 我笑而不...
    開(kāi)封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮蓝撇,結(jié)果婚禮上果复,老公的妹妹穿的比我還像新娘。我一直安慰自己渤昌,他們只是感情好虽抄,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著独柑,像睡著了一般迈窟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上忌栅,一...
    開(kāi)封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天车酣,我揣著相機(jī)與錄音,去河邊找鬼索绪。 笑死湖员,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的瑞驱。 我是一名探鬼主播娘摔,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼唤反!你這毒婦竟也來(lái)了凳寺?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤彤侍,失蹤者是張志新(化名)和其女友劉穎读第,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體拥刻,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年父泳,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了般哼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡惠窄,死狀恐怖蒸眠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杆融,我是刑警寧澤楞卡,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響蒋腮,放射性物質(zhì)發(fā)生泄漏淘捡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一池摧、第九天 我趴在偏房一處隱蔽的房頂上張望焦除。 院中可真熱鬧,春花似錦作彤、人聲如沸膘魄。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)创葡。三九已至,卻和暖如春绢慢,著一層夾襖步出監(jiān)牢的瞬間灿渴,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工呐芥, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留逻杖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓思瘟,卻偏偏與公主長(zhǎng)得像荸百,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子滨攻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理够话,服務(wù)發(fā)現(xiàn),斷路器光绕,智...
    卡卡羅2017閱讀 134,601評(píng)論 18 139
  • Scala與Java的關(guān)系 Scala與Java的關(guān)系是非常緊密的E啊! 因?yàn)镾cala是基于Java虛擬機(jī)诞帐,也就是...
    燈火gg閱讀 3,421評(píng)論 1 24
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法欣尼,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法停蕉,繼承相關(guān)的語(yǔ)法愕鼓,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,587評(píng)論 18 399
  • 挑戰(zhàn)為愛(ài)朗讀記錄100NO.03 《螢火蟲(chóng)女孩》彭懿作者 李海燕繪者 《我的第一本認(rèn)識(shí)書 數(shù)字 顏色 形狀》 今天...
    芯施施媽媽閱讀 313評(píng)論 0 0
  • 這條街道是熟悉的 用十幾年的光陰來(lái)熟悉她 曾經(jīng)的感覺(jué)慧起,她是我的束縛 想要走出這條街道菇晃。如今 真的走出去了,再次走在...
    利君理療閱讀 291評(píng)論 0 0