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

嘟嘟dududu發表於2018-08-21

在使用Flutter構建WhatsApp之前,我們建立了一個帶有選項卡和導航的基本appbar。 今天,我們將使用ListView.builder建立聊天的滾動列表

隨著介紹,這裡是我們將要構建的截圖

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

#設定模型

在我們構建List之前,我們將為聊天構建模板。 我們首先在lib資料夾中建立一個名為“model”的新資料夾。 在模型資料夾中,建立名為chat_model.dart的檔案。 建立檔案後,我們現在可以開始構建結構了。 我們將從建立ChatModel類開始。

class ChatModel {

}
複製程式碼

在這個類中,我們將為我們想要聊天列表的功能建立變數。 WhatsApp通常具有訊息的人物,姓名,時間和訊息的片段。

建立不同的變數,將它們分配給型別字串。 它們被設定為final,因為我們只設定一次值。 如果您想了解有關dart中不同變數型別的更多資訊,請檢視dart變數介紹視訊


class ChatModel {
  final String username;
  final String message; 
  final String time;
  final String avatarurl;
}
複製程式碼

很好,宣告瞭變數,我們現在可以將它傳遞給類的建構函式

這是通過以下程式碼行完成的

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

接下來,我們繼續建立一個聊天列表。 為此,我們建立一個名為data的變數,它將是List型別。 該列表將是ChatModel型別。 這可確保輸入的資料遵循類中列出的格式。

List<ChatModel> 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'
 ),] ;
複製程式碼

在上面的程式碼中,我們建立了七個帶有訊息的使用者。 每個模型都遵循我們建立的格式。 您可以編輯此項以包含任意數量的使用者。 使用建立聊天的模板,我們現在可以移動到實際列表檢視。

#列表檢視

首先,我們開啟chat_screen.dart並匯入剛剛建立的檔案。

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

接下來,我們將小部件從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<ChatScreen> {
  @override
  Widget build(BuildContext context) {
    return new Container();
  }
}
複製程式碼

是時候去玩有趣的東西,用ListView.builder替換Container。 ListView允許我們在螢幕上顯示滾動的小部件陣列。 它有許多不同的屬性,但我們將要使用的是itemCount和itemBuilder。 itemCount不應等於零。 itemBuilder用於構建列表的專案。 它需要一種與Stateful和Stateless小部件非常相似的構建方法。 主要區別在於新增索引變數。

Stateless/Stateful

(BuildContext context)

itemBuilder

(BuildContext context, int index)

修改ChatScreen

class ChatScreen extends StatefulWidget {
  _ChatScreen createState() => new _ChatScreen();
}

class _ChatScreen extends State<ChatScreen> {
  @override
  Widget build(BuildContext context) {
    return new Container();
  }
}
複製程式碼

To

class ChatScreen extends StatefulWidget {
  _ChatScreen createState() => new _ChatScreen();
}

class _ChatScreen extends State<ChatScreen> {
  @override
  Widget build(BuildContext context) {
    return new ListView.builder(
      itemCount: 
       itemBuilder: (BuildContext context, int index) {}
    );
  }
}
複製程式碼

對於我們的itemCount,我們將使用之前建立的資料列表的長度。 只需data.length的值

接下來,我們將處理聊天專案。 在itemBuilder中,建立一個新列。 該列是一個小部件,它在垂直陣列中顯示其子節點。

正如您在WhatsApp中所注意到的那樣,每條聊天都有一條細細的灰色線條。 要映象此效果,我們使用Divider小部件。 這個小部件允許我們用螢幕分隔螢幕上的元素。 高度,顏色和縮排都可以改變,現在,我們只需要設定10.0的高度(數字必須是小數值)。

建立Divider後,我們將移至ListTile。 這是另一個預製的Flutter小部件,它易於使用但功能非常強大。 有不同的屬性,如leading, title 和 subtitle都'baked in'。 在Divider下,我們通過鍵入新的ListTile()來建立小部件。

您的_ChatScreen類應如下所示


 class _ChatScreen extends State<ChatScreen> {
  @override
  Widget build(BuildContext context) {
    return new ListView.builder(
      itemCount: data.length,
      itemBuilder: (BuildContext context, int index) {
        return new Column(
          children: <Widget>[
            new Divider(
              height: 10.0,
            ),
            new ListTile(
            ),
          ],
        );
      },
    );
  }
}
複製程式碼

首先,我們從Circle Avatar開始。 這是訊息左側的圖片,以使用者的圖片為特色。 這在Flutter中建立非常簡單。 在列表磁貼中,我們將leading屬性設定為新的Circle頭像。 然後我們指定它的背景顏色和背景影象。 背景顏色可以是您喜歡的任何顏色,在此示例中我使用灰色。 對於背景影象,我們使用網路影象。 傳入我們資料列表中的頭像URL。使用以下程式碼完成:

new ListTile( 
 leading: new CircleAvatar(
 backgroundColor: Colors.grey, 
 backgroundImage: new NetworkImage(data[index].avatarurl), 
 ),
複製程式碼

注意對於NetworkImage,我們指定data [index]。 傳遞的索引來自itemBuilder中建立的索引。 對於每次迭代,索引都會改變。

建立我們的頭像後,我們會將注意力轉移到使用者名稱和時間/日期。 由於這兩個位於同一行,我們可以使用Row小部件。 這與列非常相似,除了不是垂直對齊,小部件水平對齊。

title: new Row(
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
    children: <Widget>[
      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))
    ],
  ),
複製程式碼

同樣,我們使用資料列表中的資訊,傳入索引。 此外,我們使用Text小部件的style屬性來相應地設定它們的樣式。

最後,訊息片段。 為此,我們將使用subtitle屬性。 建立一個容器視窗小部件,它將在文字視窗小部件的頂部新增5.0填充,該視窗小部件將分配給其子視窗。 “文字”視窗小部件將顯示該使用者的資料列表中的訊息。 索引再次傳入。文字的樣式也會更改,以便增加字型大小和不同顏色。

您的檔案現在應該如下所示

import 'package:flutter/material.dart';
import '../model/chat_model.dart';

class ChatScreen extends StatefulWidget {
  _ChatScreen createState() => new _ChatScreen();
}

class _ChatScreen extends State<ChatScreen> {
  @override
  Widget build(BuildContext context) {
    return new ListView.builder(
      itemCount: data.length,
      itemBuilder: (BuildContext context, int index) {
        return new Column(
          children: <Widget>[
            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: <Widget>[
                  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) ), ),
            )
          ],
        );
      },
    );
  }
}
複製程式碼

現在,如果你重新載入你的應用程式,你應該看到一個可操作的,可滾動的聊天列表。

相關文章