2024年最全Android&Navigation全面介绍&全新的Fragment管理器,2024年最新面试必问10大问题回答面试常问问题

学习宝典

对我们开发者来说,一定要打好基础,随时准备战斗。不论寒冬是否到来,都要把自己的技术做精做深。虽然目前移动端的招聘量确实变少了,但中高端的职位还是很多的,这说明行业只是变得成熟规范起来了。竞争越激烈,产品质量与留存就变得更加重要,我们进入了技术赋能业务的时代。

不论遇到什么困难,都不应该成为我们放弃的理由!

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我针对Android程序员,我这边给大家整理了一套学习宝典!包括不限于高级UI、性能优化、移动架构师、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【算法合集】

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

app:startDestination=“@+id/home_dest” 指定初始目标

navigation可以嵌套navigation标签.在布局编辑器中会显示为:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

嵌套navigation无法互相关联





上面的mainFragment无法直接app:destination="@id/settingFragment"这会导致运行错误. 只能先导航到navigation.(即NavHostFragment所在的界面)

fragment 节点

android:id 不言而喻

android:name 目标要实例化的fragment完全限定类名

tools:layout 用于显示在布局编辑器

android:label 用于后面绑定Toolbar等自动更新标题

argument 节点

android:name=“myArg”
app:argType=“integer”
android:defaultValue=“0”

  • 参数名称
  • 参数类型
  • 参数默认值

在跳转导航页面的时候会自动在argument中带上参数(要求指定参数默认值). 数组和Paraclable/Serializable不支持默认值设置, 通过下面要讲的SafeArg可以在编译器校验参数类型安全问题.

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

action 节点

动作 用于页面跳转时指定目标页面

android:id=“@+id/next_action”
动作id
app:destination=“@+id/flow_step_two_dest”>
目标页面
app:popUpTo=“@id/home_dest”
当前属于弹出栈
app:popUpToInclusive=“true/false”
弹出栈是否包含目标
app:launchSingleTop=“true/false”
是否开启singleTop模式

app:enterAnim=“”
app:exitAnim=“”
导航动画

app:popEnterAnim=“”
app:popExitAnim=“”
弹出栈动画

如果从导航页面到新的Activity页面, 动画不支持. 请使用默认的Activity设置动画去支持.

全局动作

NavController只能使用当前页面在XMl中的节点的子节点action. 不能使用其他的Fragment下的动作.

但是可以通过直接给navigation标签创建子标签action, 这属于全局动作, 即每个Fragment都能使用的动作.

占位页

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

占位页面如果运行时没有指定Class并且导航到该占位页面时会抛出异常

总结

一般情况下我们其实只会在XML中定义Fragment节点.

这些action|argument节点我认为主要是给SafeArgsGradle插件使用. 用于给插件扫描自动生成类比较方便, 如果不使用插件我不建议使用者两个节点, 在文章末尾会详细提及如果使用该插件. 该插件主要是自动处理参数的传递和获取以及目的地跳转.

类关系

NavController 控制导航的跳转和弹出栈

NavOptions 控制跳转过程中的配置选项, 例如动画和singleTop模式

Navigation 工具类 创建点击事件或者获取控制器 (鸡肋), 自己实现扩展函数可能更加方便.

NavHostFragment 导航的容器, 可以设置和获取导航图(NavGraph)

NavGraph 用于描述导航中页面关系的对象 可以增删改查页面,设置起始页等

NavigationUI 用于将导航和一系列菜单控件自动绑定的工具类

Navigator 页面的根接口, 如果想创建一个新的类型页面就要自定义他

NavigatorProvider 一个内部保存着[名称:Navigator]键值对的HashMap. 一般情况不需要使用.

NavDeepLinkBuilder 构建一个能打开导航页面的Intent

NavInflater 用于将XML创建成NavGraph对象, NavController可以通过更方便的函数创建不需要直接使用这个类.

void NavInflater(@NonNull Context context,
@NonNull NavigatorProvider navigatorProvider) // 要求当前NavHostFragment的内部变量
// 构造函数, 但一般情况使用NavController.getNavInflater获取对象

void NavGraph inflate(@NavigationRes int graphResId)

NavBackStackEntry 表示一个目的地所对应

NavController

NavController用于跳转页面和参数传递等控制, 可以通过扩展函数得到实例.

通过三个扩展函数可以得到实例

  1. Fragment.findNavController()
  2. View.findNavController()
  3. Activity.findNavController(viewId: Int) // NavHostFragment的Id

navigate

跳转目的

public void navigate(@IdRes int resId,
@Nullable Bundle args,
@Nullable NavOptions navOptions,
@Nullable Navigator.Extras navigatorExtras) // 可设置共享元素动画参数

public void navigate(Uri deepLink,
NavOptions navOptions,
Navigator.Extras navigatorExtras)

  • resId都是可选参数

通过实现抽象类NavDirections创建自定义的对象来描述跳转目标(action)和传参(bundle)

public void navigate (NavDirections directions,
NavOptions navOptions,
Navigator.Extras navigatorExtras)

  • directions都是可选参数

resId可以是XML中的action或者destination节点id, 如果是action则会附带action的配置, 如果是destination则不会附带destination节点下的子节点action(写了白写).

args 即需要在fragment之间传递的Bundle参数, 但是导航还支持另外一种插件形式的传递参数方式-安全参数SafeArgs, 后面提到.

navOptions 即导航页面一些配置选项(例如动画)

返回上级

public boolean navigateUp ()
public boolean navigateUp (DrawerLayout drawerLayout)
public boolean navigateUp (AppConfiguration appConfiguration)

出栈

弹出栈, 即从Nav回退栈中清除Fragment.

public boolean popBackStack (int destinationId, // 目标id
boolean inclusive) // 是否包含参数目标

public boolean popBackStack ()
// 弹出当前Fragment

目的地变化监听器

每次进行跳转等页面变化时都会回调该监听器

public void addOnDestinationChangedListener (NavController.OnDestinationChangedListener listener)
public void removeOnDestinationChangedListener (NavController.OnDestinationChangedListener listener)

public interface OnDestinationChangedListener {
/**

  • 导航完成以后回调函数(但是可能动画还在播放中)
  • @param 控制导航到目标的导航控制器NavController
  • @param 目标页面
  • @param 导航到目标页面的参数
    */
    void onDestinationChanged(@NonNull NavController controller,
    @NonNull NavDestination destination, @Nullable Bundle arguments);
    }

DeepLink

NavDeepLinkBuilder createDeepLink ()
// 内部就是调用的DeepLinkBuilder的构造函数

boolean handleDeepLink(Intent intent)

NavDestination getCurrentDestination ()

NavigatorProvider getNavigatorProvider ()

NavInflater getNavInflater()

Bundle saveState ()
void restoreState (Bundle navState)
// 用于处理NavController的状态获取和恢复

关于NavGraph函数

void setGraph(NavGraph graph,
Bundle startDestinationArgs);

void setGraph(int graphResId,
Bundle startDestinationArgs);

NavGraph getGraph ()

  • startDestinationArgs可选参数, 用于传递给起始目的地的参数对象

NavDirections

一个抽象类用于自定义动作和参数, 如果你想复用某个跳转逻辑就可以自定义继承该类. 一般情况下我们并不会手动去继承该类因为过于麻烦, 这个类主要是用于SafeArgs插件自动生成的派生类.

Navigator.Extras

前面提到参数 navigatorExtras 目前是用于支持转场动画的共享元素.

通过扩展函数可以快速创建

fun FragmentNavigatorExtras(vararg sharedElements: Pair<View, String>)

fun ActivityNavigatorExtras(activityOptions: ActivityOptionsCompat? = null, flags: Int = 0)

可以从源码看到内部都是使用的Navigator.Extras.Builder构造器创建的.

NavOptions

属于导航时的附加选项设置

XML示例

创建NavOptions对象相当于代码动态实现了XML中的<action>标签的属性设置(但是无法指定目标).

目前功能只有设置动画和singleTop(启动模式), popUp(弹出栈)

创建对象

提供一个DSL作用域

fun navOptions(optionsBuilder: NavOptionsBuilder.() -> Unit): NavOptions

示例

val options = navOptions {
anim {
enter = R.anim.slide_in_right // 进入页面动画
exit = R.anim.slide_out_left
popEnter = R.anim.slide_in_left // 弹出栈动画
popExit = R.anim.slide_out_right
}

launchSingleTop = true
popUpTo = R.id.categoryFragment
}

findNavController().navigate(R.id.flow_step_one_dest, null, options)

弹出栈

public NavOptions.Builder setPopUpTo (int destinationId,
boolean inclusive)

函数并不会决定目的地, 只是在导航到目的地之前先执行一个弹出栈指令.

场景: 例如我现在购买一个商品支付成功, 这个时候我要将前面的商品详情; 订单配置等页面全部关闭 然后进入<支付成功>页面

顺便说下在之前的做法是发送事件然后finish

NavDestination

表示当前目标对象

NavController可以获取NavDestination

findNavController().currentDestination

函数

void addDeepLink(String uriPattern)
boolean hasDeepLink(Uri deepLink)

Navigator getNavigator()
NavGraph getParent()

NavAction getAction(int id)
void putAction(int actionId, NavAction action)
void putAction(int actionId, int destId)
void removeAction(int actionId)

void setDefaultArguments(Bundle args)
void addDefaultArguments(Bundle args)
Bundle getDefaultArguments()

void setId(int id)
int getId()

void setLabel(CharSequence label)
CharSequence getLabel()

NavHostFragment

该对象为Navigation提供一个容器

一般使用情况是在布局中直接定义, 但是也可以通过代码构建实例, 然后通过代码创建视图(例如ViewPager等)

public static NavHostFragment create (int graphResId)

UI绑定

Navigation可以与一系列视图组件进行联动

BottomNavigationView

通过扩展函数可以绑定多个导航图, 且关联BNV.

fun BottomNavigationView.setupWithNavController(
navGraphIds: List,
fragmentManager: FragmentManager,
containerId: Int,
intent: Intent
): LiveData

  • navGraphIds 集合中包含navGrap的Id. 每个BNV的按钮对应一个navGrap.

ActionBar

设置导航到新页面时自动更新标题文字

fun AppCompatActivity.setupActionBarWithNavController(
navController: NavController,
drawerLayout: DrawerLayout?
)

fun AppCompatActivity.setupActionBarWithNavController(
navController: NavController,
configuration: AppBarConfiguration = AppBarConfiguration(navController.graph)
)

这里出现个参数AppBarConfiguration, 用于配置Toolbar/ActionBar/CollapsingToolbarLayout.

AppBarConfiguration

构造器模式使用Builder创建实例

AppBarConfiguration.Builder(NavGraph navGraph)
AppBarConfiguration.Builder(Menu topLevelMenu)
AppBarConfiguration.Builder(int… topLevelDestinationIds)
AppBarConfiguration.Builder(Set topLevelDestinationIds)
// 构造函数效果等同

函数

AppBarConfiguration.Builder setDrawerLayout(DrawerLayout drawerLayout)
// 绑定Toolbar同时绑定一个DrawerLayout联动

AppBarConfiguration.Builder setFallbackOnNavigateUpListener(AppBarConfiguration.OnNavigateUpListener fallbackOnNavigateUpListener)
// 监听返回操作

AppBarConfiguration build()

尾声

如果你想成为一个优秀的 Android 开发人员,请集中精力,对基础和重要的事情做深度研究。

对于很多初中级Android工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。 整理的这些架构技术希望对Android开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

这里,笔者分享一份从架构哲学的层面来剖析的视频及资料给大家梳理了多年的架构经验,筹备近6个月最新录制的,相信这份视频能给你带来不一样的启发、收获。

Android进阶学习资料库

一共十个专题,包括了Android进阶所有学习资料,Android进阶视频,Flutter,java基础,kotlin,NDK模块,计算机网络,数据结构与算法,微信小程序,面试题解析,framework源码!

大厂面试真题

PS:之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

《2019-2021字节跳动Android面试历年真题解析》

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

img-5Yd3FH5d-1715846756326)]

大厂面试真题

PS:之前因为秋招收集的二十套一二线互联网公司Android面试真题 (含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

[外链图片转存中…(img-d7jnRmqY-1715846756326)]

《2019-2021字节跳动Android面试历年真题解析》

[外链图片转存中…(img-agyRY6Fr-1715846756326)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值