- 原文地址:Flutter Challenge: Twitter
- 原文做者:Deven Joshi
- 译文出自:掘金翻译计划
- 本文永久连接:github.com/xitu/gold-m…
- 译者:MeFelixWang
挑战 Flutter 将尝试在 Flutter 中从新建立特定应用的 UI 或设计。前端
此挑战将尝试实现安卓版 Twitter 的主页。请注意,重点将放在 UI 上,而不是实际从后端服务器获取数据。android
Twitter 有四个由底部导航栏控制的主要页面。ios
它们是:git
BottomNavigationBar 有四个选项卡能够跳转到每一个页面。github
在咱们的应用中将有四个不一样的页面,只需点击 BottomNavigationBar 上的项目来切换页面。后端
建立好 Flutter 项目(我将其命名为 twitter_ui_demo )后,清除项目中的默认代码,只留下这些:bash
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(
body: new Center(
),
);
}
}
复制代码
HomePage 中有一个 Scaffold,它存有咱们的 BottomNavigationBar 以及当前激活的页面。服务器
由于底部导航栏是用于导航的主要组件,因此咱们先试着实现它。app
这是 BottomNavigationBar 的样子:less
由于没有应用中所需的图标,因此咱们将使用 Font Flutter Awesome package 。在 pubspec.yaml 中添加依赖项并引入
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
复制代码
到文件中。
BottomNavigationBar 的代码以下:
bottomNavigationBar: BottomNavigationBar(items: [
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.home, color: selectedPageIndex == 0? Colors.blue : Colors.blueGrey,),
),
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.search, color: selectedPageIndex == 1? Colors.blue : Colors.blueGrey,),
),
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.bell, color: selectedPageIndex == 2? Colors.blue : Colors.blueGrey,)
),
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.envelope, color: selectedPageIndex == 3? Colors.blue : Colors.blueGrey,),
),
], onTap: (index) {
setState(() {
selectedPageIndex = index;
});
}, currentIndex: selectedPageIndex)
复制代码
将其添加到 HomePage。
请注意,当设置图标的颜色时,咱们会检查是否选中了图标,而后指定颜色。在 Twitter 中,选中的图标为蓝色,让咱们将未选择的图标设置为 blueGrey。
定义一个名为 selectedPageIndex 的整型变量,用于存储所选页面的索引。在 onTap 函数中,咱们将变量设置为新索引。用 setState() 包裹起来,由于咱们须要刷新页面来从新渲染 AppBar。
实现的底部导航栏:
让咱们构建四个基本页面,这些页面将在单击相应的图标时显示。
创建的四个页面(在不一样的文件中)以下:
用户订阅(主页)页面的代码以下:
import 'package:flutter/material.dart';
class UserFeedPage extends StatefulWidget {
@override
_UserFeedPageState createState() => _UserFeedPageState();
}
class _UserFeedPageState extends State<UserFeedPage> {
@override
Widget build(BuildContext context) {
return Container();
}
}
复制代码
相似的,咱们创建好搜索,通知和消息页面。
回到基础页面中,引入这些页面并定义成一个列表。
var pages = [
UserFeedPage(),
SearchPage(),
NotificationPage(),
MessagesPage(),
];
复制代码
在 Scaffold 中,写入
body: pages[selectedPageIndex],
复制代码
它将设置 body 来展现这些页面。
到目前为止,MyHomePage 基础组件的代码以下:
class _MyHomePageState extends State<MyHomePage> {
var selectedPageIndex = 0;
var pages = [
UserFeedPage(),
SearchPage(),
NotificationPage(),
MessagesPage(),
];
@override
Widget build(BuildContext context) {
return new Scaffold(
body: pages[selectedPageIndex],
bottomNavigationBar: BottomNavigationBar(items: [
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.home, color: selectedPageIndex == 0? Colors.blue : Colors.blueGrey,),
),
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.search, color: selectedPageIndex == 1? Colors.blue : Colors.blueGrey,),
),
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.bell, color: selectedPageIndex == 2? Colors.blue : Colors.blueGrey,)
),
BottomNavigationBarItem(
title: Text(""),
icon: Icon(FontAwesomeIcons.envelope, color: selectedPageIndex == 3? Colors.blue : Colors.blueGrey,),
),
], onTap: (index) {
setState(() {
selectedPageIndex = index;
});
}, currentIndex: selectedPageIndex,),
);
}
}
复制代码
如今,咱们将从新建立页面。
页面中有两个元素:AppBar 和推文列表。
首先制做 AppBar。它有一张用户我的资料图片和一个白底黑字的标题。
appBar: AppBar(
backgroundColor: Colors.white,
title: Text("Home", style: TextStyle(color: Colors.black),),
leading: Icon(Icons.account_circle, color: Colors.grey, size: 35.0,),
),
复制代码
咱们将使用图标而不是我的资料图片。
从新建立的 AppBar
如今,咱们须要建立推文列表。为此,咱们使用 ListView.builder()。
来看看列表项。
首先,咱们须要一个由 row 和 divider 组成的 column。
在 row 中,有一个 icon 和另外一个 column。
该 column 中有一个用于展现推文信息的 row,一个用于展现推文自己的 text,一个 image 和另外一个用于对推文应用操做(如评论等)的 row。
为简洁起见,咱们暂时抛开 image,实际上和在 row 中添加 image 同样简单。
return Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(4.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(Icons.account_circle, size: 60.0, color: Colors.grey,),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 4.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: Container(child: RichText(
text: TextSpan(
children: [
TextSpan(text:tweet.username, style: TextStyle(fontWeight: FontWeight.w600, fontSize: 18.0, color: Colors.black),),
TextSpan(text:" " + tweet.twitterHandle,style: TextStyle(fontSize: 16.0, color: Colors.grey)),
TextSpan(text:" ${tweet.time}",style: TextStyle(fontSize: 16.0, color: Colors.grey))
]
),overflow: TextOverflow.ellipsis,
)),flex: 5,
),
Expanded(
child: Padding(
padding: const EdgeInsets.only(right: 4.0),
child: Icon(Icons.expand_more, color: Colors.grey,),
),flex: 1,
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Text(tweet.tweet, style: TextStyle(fontSize: 18.0),),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Icon(FontAwesomeIcons.comment, color: Colors.grey,),
Icon(FontAwesomeIcons.retweet, color: Colors.grey,),
Icon(FontAwesomeIcons.heart, color: Colors.grey,),
Icon(FontAwesomeIcons.shareAlt, color: Colors.grey,),
],
),
)
],
),
)
],
),
),
Divider(),
],
);
复制代码
在建立一个用于提供简单推文的帮助类和一个简单的 FloatingActionButton 后,页面以下:
从新建立的 Twitter 应用
这是从新构建的 Twitter 用户订阅页。在 Flutter 中能够快速轻松地从新建立任何 UI,这说明了它的开发速度和可定制性很是不错。二者是很难兼顾的。
完整的示例托管在 Github 上。
Github 连接:github.com/deven98/Twi…
感谢阅读此 Flutter 挑战。能够留言告诉我任何你想要在 Flutter 中从新建立的应用。喜欢请给个 star,下次见。
不要错过:
若是发现译文存在错误或其余须要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可得到相应奖励积分。文章开头的 本文永久连接 即为本文在 GitHub 上的 MarkDown 连接。
掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划、官方微博、知乎专栏。