[译] 挑战 Flutter 之 WhatsApp

挑战 Flutter 之 WhatsApp

《[译] 挑战 Flutter 之 WhatsApp》
《[译] 挑战 Flutter 之 WhatsApp》

Flutter Challenges 是一项尝试利用 Flutter 重新创建特定的应用程序UI或设计的挑战。

此次挑战将尝试 Whatsapp Android 应用程序的主界面。请注意将重点放在 UI 上而不是实际获取消息。

开始

WhatsApp 的主界面包括:

  1. 一个带有搜索操作和菜单的 AppBar
  2. 在 AppBar 的底部有四个标签
  3. 一个用于拍照的相机标签
  4. 一个用于多种用途的 FloatingActionButton
  5. 一个“聊天”标签可查看所有对话
  6. 一个“状态”选项卡可查看所有状态
  7. 一个“打电话”选项卡可查看所有的通话记录

项目设置

让我们创建一个名为 whatsapp_ui 的 Flutter 项目并删除所有默认代码,只留下一个带有默认应用栏的空白屏幕。

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("WhatsApp"),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[

          ],
        ),
      ),
    );
  }
}

The AppBar

AppBar 具有应用程序的标题,以及两个操作:搜索和菜单。

将其添加到 AppBar 中,

appBar: new AppBar(
  title: new Text("WhatsApp", style: TextStyle(color: Colors.white, fontSize: 22.0, fontWeight: FontWeight.w600),),
  actions: <Widget>[
    Padding(
      padding: const EdgeInsets.only(right: 20.0),
      child: Icon(Icons.search),
    ),
    Padding(
      padding: const EdgeInsets.only(right: 16.0),
      child: Icon(Icons.more_vert),
    ),
  ],
  backgroundColor: whatsAppGreen,
),

代码结果如下:

现在继续

The Tabs

tabs(选项卡)是 AppBar 的简单扩展,Flutter 使它们非常容易实现。

AppBar 有一个“底部”字段,用于保存我们的标签:

bottom: TabBar(
  tabs: [
    Tab(icon: Icon(Icons.camera_alt),),
    Tab(child: Text("CHATS"),),
    Tab(child: Text("STATUS",)),
    Tab(child: Text("CALLS",)),
  ], indicatorColor: Colors.white,
),

此外,我们需要一个 TabController 来实现这一点。

创建一个新的 TabController。

TabController tabController;

@override
void initState() {
  // TODO: implement initState
  super.initState();

  tabController = TabController(vsync: this, length: 4);

}

现在将该控制器添加到 TabBar 的 “controller” 字段中。

bottom: TabBar(
  tabs: [
    Tab(icon: Icon(Icons.camera_alt),),
    Tab(child: Text("CHATS"),),
    Tab(child: Text("STATUS",)),
    Tab(child: Text("CALLS",)),
  ], indicatorColor: Colors.white,
  controller: tabController,
),

而对于 TabBarView

body: TabBarView(
  controller: tabController,
  children: [
    Icon(Icons.camera_alt),
    Text("Chat Screen"),
    Text("Status Screen"),
    Text("Call Screen"),
  ],
),

《[译] 挑战 Flutter 之 WhatsApp》
《[译] 挑战 Flutter 之 WhatsApp》

现在,在转到各个页面之前,我们将添加选项卡所代表的页面。用以下方法切换脚手架的现有“正文”代码:

body: TabBarView(
  children: [
    Icon(Icons.camera_alt),
    Text("Chat Screen"),
    Text("Status Screen"),
    Text("Call Screen"),
  ],
),

子项代表选项卡所用的页面。现在整个页面都是一个 Text 小部件。

悬浮按钮

Floating Action Button 根据屏幕上的页面而变化。

首先在脚手架中添加一个 FloatingActionButton。

floatingActionButton: FloatingActionButton(
  onPressed: () {
  },
  child: fabIcon,
  backgroundColor: whatsAppGreenLight,
),

“fabIcon” 字段只存储要显示的图标,因为我们需要根据显示的屏幕更改显示的图标。

要监听选项卡选定的更改,需要给 TabController 添加一个监听器。

tabController = TabController(vsync: this, length: 4)
  ..addListener(() {

  });

现在,当标签控制器实现页面已更改时,请更改 FAB 图标。

tabController = TabController(vsync: this, length: 4)
  ..addListener(() {
    setState(() {
      switch(tabController.index) {
        case 0:
          break;
        case 1:
          fabIcon = Icons.message;
          break;
        case 2:
          fabIcon = Icons.camera_enhance;
          break;
        case 3:
          fabIcon = Icons.call;
          break;
      }
    });
  });

《[译] 挑战 Flutter 之 WhatsApp》
《[译] 挑战 Flutter 之 WhatsApp》

继续,

聊天界面

聊天屏幕有一个我们需要显示的消息列表。要创建消息列表,我们使用 ListView.builder() 并构造我们的项目。

让我们来看看聊天界面的列表项。

《[译] 挑战 Flutter 之 WhatsApp》
《[译] 挑战 Flutter 之 WhatsApp》

最外面的小部件是一行图标和另一行

第二行内部是一列,包含一行和一个文本小部件。

该行具有标题和消息日期。

让我们构建一个聊天项模型作为用于存储列表项详细信息的类。

class ChatItemModel {

  String name;
  String mostRecentMessage;
  String messageDate;

  ChatItemModel(this.name, this.mostRecentMessage, this.messageDate);

}

现在,为简洁起见,我省略了添加个人资料图片。

itemBuilder: (context, position) {
  ChatItemModel chatItem = ChatHelper.getChatItem(position);

  return Column(
    children: <Widget>[
      Padding(
        padding: const EdgeInsets.all(8.0),
        child: Row(
          children: <Widget>[
            Icon(
              Icons.account_circle,
              size: 64.0,
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Row(
                      mainAxisAlignment:
                          MainAxisAlignment.spaceBetween,
                      children: <Widget>[
                        Text(
                          chatItem.name,
                          style: TextStyle(
                              fontWeight: FontWeight.w500,
                              fontSize: 20.0),
                        ),
                        Text(
                          chatItem.messageDate,
                          style: TextStyle(color: Colors.black45),
                        ),
                      ],
                    ),
                    Padding(
                      padding: const EdgeInsets.only(top: 2.0),
                      child: Text(
                        chatItem.mostRecentMessage,
                        style: TextStyle(
                            color: Colors.black45, fontSize: 16.0),
                      ),
                    )
                  ],
                ),
              ),
            )
          ],
        ),
      ),
      Divider(),
    ],
  );
},

创建第一个列表后,结果如下:

我们可以类似地在其他屏幕上的屏幕上创建其他选项卡。完整的示例托管在GitHub上。

GitHub 链接 : https://github.com/deven98/WhatsappFlutter

感谢您阅读此 Flutter 挑战。随意提及您可能想要在 Flutter 中重新创建的任何应用程序。如果你喜欢它,一定要留下掌声,再见。

不要忘了:The Medium App in Flutter

如果发现译文存在错误或其他需要改进的地方,欢迎到
掘金翻译计划 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的
本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。

掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为
掘金 上的英文分享文章。内容覆盖
Android
iOS
前端
后端
区块链
产品
设计
人工智能等领域,想要查看更多优质译文请持续关注
掘金翻译计划
官方微博
知乎专栏

    原文作者:少年闰土
    原文地址: https://zhuanlan.zhihu.com/p/41902725
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞