从0开始写一个基于Flutter的开源中国客户端(1)
Widget build(BuildContext context) {
return new MaterialApp(
theme: new ThemeData(
// 设置页面的主题色
primaryColor: const Color(0xFF63CA6C)
),
home: new Scaffold(
appBar: new AppBar(
// 设置AppBar标题
title: new Text(“My OSC”,
// 设置AppBar上文本的样式
style: new TextStyle(color: Colors.white)
),
// 设置AppBar上图标的样式
iconTheme: new IconThemeData(color: Colors.white)
),
body: new Text(“MyOSC Client”)
),
);
}
}
上面的代码中,为MaterialApp设置了theme参数,主要是为了改变页面主题颜色为绿色,在Scaffold的appBar属性中,为title设置了颜色为白色,如果不设置的话,默认为黑色,appBar的iconTheme属性也设置为了白色主题,如果不设置的话,AppBar上的图标默认为黑色。
编写4个页面用于切换显示
在新建的Flutter项目的lib/目录下,新建一个pages/目录,该目录用于存放App中的所有页面,然后分别创建四个.dart文件:NewsListPage.dart TweetsListPage.dart DiscoveryPage.dart MyInfoPage.dart,代表App中首页底部4个Tab切换时分别显示的页面,这四个页面暂时就在页面正中间显示一行文本,下面是资讯列表NewsListPage.dart代码:
// pages/NewsListPage.dart
import ‘package:flutter/material.dart’;
// 资讯列表页面
class NewsListPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Center(
child: new Text(“NewsListPage”),
);
}
}
其余三个页面代码跟上面的类似,只是换了类名和Text组件的文本。
在上一步中,我们的Scaffold组件里的body属性只是一个Text组件,为了加载上面的4个页面,需要用一个容器组件将这4个页面装起来,然后在点击Tab时切换页面,这就用到了我之前的博文里说到的IndexedStack组件了。IndexedStack中可以有多个子组件,根据索引值来显示其中某个组件而隐藏其余的组件。
在第一步中MyOSCClientState类中定义两个变量:_tabIndex和_body,_tabIndex表示当前页面底部选中的Tab的索引,_body表示首页Scaffold组件的body属性值,然后给_tabIndex和_body变量赋值,如下代码所示:
// 页面当前选中的Tab的索引
int _tabIndex = 0;
// 页面body部分组件
var _body = new IndexedStack(
children: [
new NewsListPage(),
new TweetsListPage(),
new DiscoveryPage(),
new MyInfoPage()
],
index: _tabIndex,
);
上面用IndexedStack加载了4个页面用于切换Tab时显示,但是Tab我们还没有做出来,Flutter中为页面添加底部导航Tab菜单很简单,已经有很多组件可以用了。
编写页面底部导航Tab菜单
给页面添加底部导航Tab菜单只需要给Scaffold组件添加一个bottomNavigationBar属性即可,这里的bottomNavigationBar我们用Flutter提供的CupertinoTabBar组件。
CupertinoTabBar是Flutter内置的iOS风格的选项卡,用于在页面底部显示几个Tab,要使用Cupertino风格的组件,必须先导入头文件,如下代码:
import ‘package:flutter/cupertino.dart’;
CupertinoTabBar组件的用法也比较简单,代码如下:
new CupertinoTabBar(
items: getBottomNavItems(),
currentIndex: _tabIndex,
onTap: (index) {
// 底部TabItem的点击事件处理,点击时改变当前选择的Tab的索引值,则页面会自动刷新
setState((){
_tabIndex = index;
});
},
)
其中items是一个List<BottomNavigationBarItem>对象,currentIndex表示当前选中的Tab的索引值,onTap是TabItem点击事件,上面的代码中,getBottomNavItems()方法代码如下:
List getBottomNavItems() {
List list = new List();
for (int i = 0; i < 4; i++) {
list.add(new BottomNavigationBarItem(
icon: getTabIcon(i),
title: getTabTitle(i)
));
}
return list;
}
// 根据索引值确定Tab是选中状态的样式还是非选中状态的样式
TextStyle getTabTextStyle(int curIndex) {
if (curIndex == _tabIndex) {
return tabTextStyleSelected;
}
return tabTextStyleNormal;
}
// 根据索引值确定TabItem的icon是选中还是非选中
Image getTabIcon(int curIndex) {
if (curIndex == _tabIndex) {
return tabImages[curIndex][1];
}
return tabImages[curIndex][0];
}
// 根据索引值返回页面顶部标题
Text getTabTitle(int curIndex) {
return new Text(
appBarTitles[curIndex],
style: getTabTextStyle(curIndex)
);
}
由于TabItem是由一个图标和一个文本组件构成,所以这里还需要在MyOSCClientState类中定义两个变量tabImages和appBarTitles。tabImages是一个二维数组,表示TabItem中的图标(包括选中和未选中状态的图标),appBarTitles是一个字符串数组,表示每个TabItem对应的页面标题,这两个变量的赋值代码如下:
// 页面底部TabItem上的图标数组
var tabImages;
// 页面顶部的大标题(也是TabItem上的文本)
var appBarTitles = [‘资讯’, ‘动弹’, ‘发现’, ‘我的’];
// 数据初始化,包括TabIcon数据和页面内容数据
void initData() {
if (tabImages == null) {
tabImages = [
[
getTabImage(‘images/ic_nav_news_normal.png’),
getTabImage(‘images/ic_nav_news_actived.png’)
],
[
getTabImage(‘images/ic_nav_tweet_normal.png’),
getTabImage(‘images/ic_nav_tweet_actived.png’)
],
[
getTabImage(‘images/ic_nav_discover_normal.png’),
getTabImage(‘images/ic_nav_discover_actived.png’)
],
[
getTabImage(‘images/ic_nav_my_normal.png’),
getTabImage(‘images/ic_nav_my_pressed.png’)
]
];
}
}
// 传入图片路径,返回一个Image组件
Image getTabImage(path) {
return new Image.asset(path, width: 20.0, height: 20.0);
}
上面的代码中需要注意的是Image组件,要使用image/目录下的图片,必须确保项目根目录下的pubspec.yaml文件中已经添加了图片的路径,如下图:

如果没有上面的assets配置,直接加载图片是会报错的。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。







既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)

总结
最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上相关的我搜集整理的14套腾讯、字节跳动、阿里、百度等2021面试真题解析,我把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包知识脉络 + 诸多细节。




网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
b5a486d4c3ab8389e65ecb71ac0)
AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算
更多推荐



所有评论(0)