先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
正文
我们在基础模板计数器上做修改,新建一个路由:
class NewRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(“Rikka Route”),
),
body: Center(
child: Text(“This is Rikka Route”),
),
);
}
}
上面代码中,我们通过继承了一个StatelessWidget来实现一个新的界面,接下来我们要进入到这个界面中,我们在初始的界面_MyHomePageState
的Column
下添加一个按键,FaltButton
,并设置点击事件实现跳转:
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
…
FlatButton(
child: Text(“open Rikka route”),
textColor: Colors.blue,
onPressed: () {
//导航到新路由
Navigator.push(context, MaterialPageRoute(builder: (context) {
return NewRoute();
}));
},
)
],
}
运行后效果如下:
点击蓝色按钮之后:
在上面新建一个页面的时候,我们可以知道 Navigator
相当于路由栈。
我们向其中push一个 MaterialPageRoute(context,build)
。
MaterialPageRoute
继承自 PageRoute
类,PageRoute类是一个抽象类,表示占有整个屏幕空间的一个模态路由页面,还定义了过渡动画的接口和属性。MaterialPageRoute
是一个组件,它可以针对不同的平台,实现与平台风格一致的路由切换动画。
我们来看看其构造函数的可选参数:
MaterialPageRoute({
WidgetBuilder builder,
RouteSettings settings,
bool maintainState = true,
bool fullscreenDialog = false,
})
- WidgetBuilder
它是一个回调函数,作用是构建路由页面的具体内容,返回值是一个widget,而路由器的实例正是一个Widget,所以我们传入新路由的构造函数,其实就是去创建这个路由
- RouteSettings
包含路由的配置信息,如路由名称、是否初始路由(首页)
- maintainState
默认情况下,当入栈一个新路由时,原来的路由仍然会被保存在内存中,如果想在路由没用的时候释放其占用的所有资源,可以设置 maintainState
为false
- fullscreenDialog
表示新的路由是否是一个全屏的对话框。
Navigator
是一个路由管理的组件,它提供了打开和退出路由的方法。它维护一个栈,管理活动路由集合。通常当前屏幕显示的页面就是栈顶的路由。
这里我们介绍最常用的两个方法:
1.Future push(BuildContext context, Route route)
将给定的路由入栈(即打开新的页面),返回值是一个 Future
对象,用以接收新路由出栈(即关闭)时的返回数据。
2.bool pop(BuildContext context, [ result ])
将栈顶路由出栈, result
为页面关闭时返回给上一个页面的数据。
我们很多时候,都在要跳转到新的界面时带入一些值,就和Android Java开发里,需要Intent去带入一些值。一遍下一个界面展示。下面我们来看看路由是怎么传值的:
下面为一个新的路由
class TipRoute extends StatelessWidget {
TipRoute({
Key key,
@required this.text, //@required 接收一个text参数
}) : super(key: key);
final String text;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(“提示”),
),
body: Padding(
padding: EdgeInsets.all(18),
child: Center(
child: Column(
children: [
Text(text),
RaisedButton(
onPressed: () => Navigator.pop(context, “这里是Rikka 的返回值”),
child: Text(“返回”),
)
],
),
),
),
);
}
}
打开的页面如下:
class RouterTestRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
onPressed: () async {
// 打开 TipRoute,并等待返回结果
var result = await Navigator.push(context,
MaterialPageRoute(builder: (context) {
return TipRoute(text: “我是Rikka”);
}));
//输出 路由返回结果
print(“路由返回值: $result”);
},
child: Text(“打开提示页”)),
);
}
}
效果如下:
点击返回后打印出:
I/flutter (24716): 路由返回值: 这里是Rikka 的返回值
我们可以先给路由起一个名称,然后就可以通过路由名字直接打开新的路由了,这样的方式更直观更简单。
想要使用命名路由,我们必须先提供并注册一个路由表,这样应用程序才知道哪个名字与哪个路由组件对应。注册路由表就是给路由起名字,路由表的定义如下:
Map<String, WidgetBuilder> routes;
是一个Map,key为路由名称,value为build的回调函数。也就是说,我们通过一个名字打开一个路由,他回去路由表里面找到这个构建函数并调用它。
那么我们如何去注册一个路由表呢?举个例子,我们在MyApp类的build方法中找到MaterialApp,添加routues属性:
return MaterialApp(
title: ‘Flutter Demo’,
theme: ThemeData(
//主题颜色
primarySwatch: Colors.lightBlue,
),
routes: {
“rikka_page”: (context) => RouterTestRoute(),
…//其他路由名称
},
//应用首页路由
home: MyHomePage(title: ‘Flutter Demo Home Page’),
);
可以看到除了home之外,都可以进行注册,那么如果我们也想注册首页路由的名称怎么办,可以这样:
return MaterialApp(
…
initialRoute: “main”, //名为"main"的路由作为应用的首页
routes: {
“rikka_page”: (context) => RouterTestRoute(),
“main”: (context) => MyHomePage(title: ‘Flutter Demo Home Page’), //注册首页路由
},
);
可以看到我们通过 initialRoute
来决定哪个是home,并在 routes
中声明,这样,我们就不用在后面定义 home
这个属性了。
接下来通过路由名打开新路由
要通过路由名称来打开新路由,可以使用 Navigator 的 pushNamed
方法:
就比如上面的我们给 RouterTestRoute
取了一个"rikka_page"的名称,那我们要去该路由页下通过 RouteSetting
对象获取路由参数:
class RouterTestRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
var args = ModalRoute.of(context).settings.arguments;
print(args);
…
}
}
接着在打开路由时传递参数:
Navigator.of(context).pushNamed(“rikka_page”, arguments: “Rikka hi”);
最后打开上一个页面后,将会打印出:
假设我们也想将上面路由传参示例中的TipRoute路由页注册到路由表中,以便也可以通过路由名来打开它。但是,由于TipRoute接受一个text 参数,我们如何在不改变TipRoute源码的前提下适配这种情况?其实很简单:
routes: {
“tip_page”: (context) {
return TipRoute(text: ModalRoute.of(context).settings.arguments);
},
…
},
MaterialApp
有一个 onGenerateRoute
属性。
如果用 pushNamed 打开命名路由时,如果指定的路由名在路由表中已经注册,则会调用路由表中的 builder函数来生成路由组件。
如果路由表中没有注册,就会调用 onGenerateRoute
来生成路由。 onGenerateRoute
回调如下:
Route Function(RouteSettings settings)
//使用时:
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute(builder: (context) {
…
});
},
onGenerateRoute只会对命名路由生效。
它应用在全局路由跳转前置处理,比如所有的路由在打开前都要检查一些东西,如果你在每个路由build()方法里面做的时候,那面会有些重复、复用性低,如果全部写在开始,则能避免这个麻烦。
使用命名路由,代码会更加好维护,因为如果使用匿名路由,则必须在调用Navigator.push的地方创建新路由页。如果使用命名路由,会更加简洁。
Android使用gradle来管理依赖包,Flutter管理包的配置文件叫做 pubspec.yaml
。yaml是一种直观、可读性高的文件格式,而且相比于JSON和XML,它更容易被解析。我们来看项目根目录下的默认配置文件:
///应用名称
name: my_app
//应用或包的描述、简介
description: A new Flutter application.
//应用或包的版本号
version: 1.0.0+1
environment:
sdk: “>=2.1.0 ❤️.0.0”
//应用或包依赖的其他包或插件
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
//开发环境依赖的工具包(不是Flutter本身依赖的包)
dev_dependencies:
flutter_test:
sdk: flutter
flutter:
//flutter相关的配置选项
uses-material-design: true
Pub仓库 http://pub.dev/ 是google官方的Dart Packages仓库,类似于Android中的jcent。
我们找到一个支持的Flutter的包,并将其导入到项目中。
写在最后
最后我想说:对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们!
这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
相信它会给大家带来很多收获:
[外链图片转存中…(img-Amri34YD-1713472550451)]
[外链图片转存中…(img-RwEvTqSw-1713472550451)]
当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-lHmksQtk-1713472550451)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!