美文网首页江苏科技大学开源社区
[译] 挑战 Flutter 之 WhatsApp

[译] 挑战 Flutter 之 WhatsApp

作者: 雇个城管打天下 | 来源:发表于2018-08-13 11:04 被阅读78次

    挑战 Flutter 之 WhatsApp

    image

    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,
    ),
    

    代码结果如下:

    image

    现在继续

    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"),
      ],
    ),
    
    image

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

    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;
          }
        });
      });
    
    image

    继续,

    聊天界面

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

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

    image

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

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

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

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

    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(),
        ],
      );
    },
    

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

    image

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

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

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

    不要忘了:The Medium App in Flutter

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


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

    相关文章

      网友评论

        本文标题:[译] 挑战 Flutter 之 WhatsApp

        本文链接:https://www.haomeiwen.com/subject/czmybftx.html