android Jetpack Navigation组件——堆栈操作和动画效果

简介: android Jetpack Navigation组件——堆栈操作和动画效果

github地址:


github分支:navigation_operation

代码入口


Navigation堆栈操作


导航的出栈操作

本章节中的两个方法都是用来出栈导航组件的,区别是popBackStack的方式更加精细


1、findNavController().navigateUp()

这个方式对导航组件进行的出栈简单粗暴,仅仅是把当前栈顶的组件进行出栈,方法的boolean型返回值表示是否出栈成功。如果如果导航失败的话我们可以主动对组件的出栈进行逻辑上的补救

代码示例
val navigarionResult = findNavController().navigateUp()
            println("是否导航出栈成功:$navigarionResult")
复制代码


2、findNavController().popBackStack(R.id.AFragment,false)

这个方法用于执行返回指定页面的操作,例如本例: 进入的时候我们点击AFragment的按钮跳转到BFragment,在BFragment中执行如下代码:

val popBackStack = findNavController().popBackStack(R.id.AFragment,false)
            println("是否返回:$popBackStack")
复制代码

就可以指定返回AFragment。

popBackStack的第二个参数说明:

true:从B返回A的时候会把A出栈,然后重新打开A

false:从B返回A的时候A不会出栈,保留跳转到B之前的状态


popUpTo 和 popUpToInclusive


先看一下我们的导航图代码

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/navigation_popup"
    app:startDestination="@id/popUpFragment">
    <fragment
        android:id="@+id/popUpFragment"
        android:name="com.mage.navigationdemo.pop.PopUpFragment"
        android:label="fragment_pop_up"
        tools:layout="@layout/fragment_pop_up" >
        <action
            android:id="@+id/action_popUpFragment_to_popAFragment"
            app:destination="@id/popAFragment" />
    </fragment>
    <fragment
        android:id="@+id/popAFragment"
        android:name="com.mage.navigationdemo.pop.PopAFragment"
        android:label="fragment_pop_a"
        tools:layout="@layout/fragment_pop_a" >
        <action
            android:id="@+id/action_popAFragment_to_popBFragment"
            app:destination="@id/popBFragment" />
    </fragment>
    <fragment
        android:id="@+id/popBFragment"
        android:name="com.mage.navigationdemo.pop.PopBFragment"
        android:label="fragment_pop_b"
        tools:layout="@layout/fragment_pop_b" >
        <action
            android:id="@+id/action_popBFragment_to_popUpFragment"
            app:popUpToInclusive="true"
            app:popUpTo="@id/popUpFragment"
            app:destination="@id/popUpFragment" />
    </fragment>
</navigation>
复制代码


这段导航图的代码实现如下效果: 从PopUpfragment跳转到PopUpAFragment再跳转到PopUpBFragment,正常情况下如果一直这么下去会无限跳转,产生无数个Fragment实例。


但是我们的代码中,在PopBFragment跳转PopUpfragment的activion中添加了popUpTo和popUpToInclusive。

其中popUpTo表示从PopBfragment回到PopUpfragment,过程中会把中间的Fragment也就是PopAFragment出栈,这样就不会同时存在多个Fragment实例了。而popUpToInclusive的作用就是在这个过程中将PopUpFragment也出栈然后重新创建。


插播一个报错


java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mage.navigationdemo/com.mage.navigationdemo.PopUpToTestActivity}: java.lang.IllegalStateException: Activity com.mage.navigationdemo.PopUpToTestActivity@a289b29 does not have a NavController set on 2131230963
复制代码

出现这个错误的场景复现:

应用首页MainActivity是一个导航图组件(NavHostFragment),我们再MainActivity的Fragment中使用startActivity方式跳转到PopUpToTestActivity,在PopUpToTestActivity的onCreate方法中调用如下代码


findNavController(R.id.nav_popuptotest).navigate(R.id.popUpFragment)
复制代码

跳到导航图PopUpFragment,然后就报了上面的错误。


解决的方式如下面的代码:

val fragment:NavHostFragment = supportFragmentManager.findFragmentById(R.id.nav_popuptotest) as NavHostFragment
fragment.navController.navigate(R.id.popUpFragment)
复制代码

即通过supportFragmentManager找到组件的NavHostFragment,利用NavHostFragment的NavController进行路由跳转


!!!讲一个 findNavController().popBackStack(R.id.AFragment,true)的坑


代码如下:

  1. 从A跳转到B
content.findViewById<Button>(R.id.btn_toBFragment).setOnClickListener {
            findNavController().navigate(R.id.action_AFragment_to_BFragment)
        }
复制代码


  1. 从B使用popBackStack(R.id.AFragment,true)返回A
val popBackStack = findNavController().popBackStack(R.id.AFragment,true)
            println("是否返回:$popBackStack")
复制代码


  1. 再从A使用导航组件跳转到B
content.findViewById<Button>(R.id.btn_toBFragment).setOnClickListener {
            findNavController().navigate(R.id.action_AFragment_to_BFragment)
        }
复制代码


第三部代码会报错:

java.lang.IllegalArgumentException: Navigation action/destination com.mage.navigationdemo:id/action_AFragment_to_BFragment cannot be found from the current destination NavGraph(com.mage.navigationdemo:id/navigation) startDestination={Destination(com.mage.navigationdemo:id/AFragment) label=fragment_a class=com.mage.navigationdemo.AFragment}
复制代码

报错的原因就是找不到导航图,

原因分析:我们返回AFragment的时候AFragment被重新创建,不再是根视图了,也就是说新的AFragment是不与我们的navigation导航图文件进行关联的,所以自然无法使用导航组件跳转到BFragment的。

此种情况应该会有解决方案的,目前先不向这个方向探索


Navigation动画


使用Navigation的时候我们可以向导航视图中添加动画,实现跳转动画过度效果。

添加过度动画的方式:

image.png

模板操作

我们可以再navigation面板中手动操作添加系统的动画模板

image.png

本例中代码效果

本例中创建两个Fragment,分别是AFragment和BFragment,我们再在AFragment跳转到BFragment,在这个跳转的action中间添加动画

效果:

image.png



相关文章
|
7月前
|
安全 Java Android开发
安卓开发中的新趋势:Kotlin与Jetpack的完美结合
【6月更文挑战第20天】在不断进化的移动应用开发领域,Android平台以其开放性和灵活性赢得了全球开发者的青睐。然而,随着技术的迭代,传统Java语言在Android开发中逐渐显露出局限性。Kotlin,一种现代的静态类型编程语言,以其简洁、安全和高效的特性成为了Android开发中的新宠。同时,Jetpack作为一套支持库、工具和指南,旨在帮助开发者更快地打造优秀的Android应用。本文将探讨Kotlin与Jetpack如何共同推动Android开发进入一个新的时代,以及这对开发者意味着什么。
|
3月前
|
测试技术 数据库 Android开发
深入解析Android架构组件——Jetpack的使用与实践
本文旨在探讨谷歌推出的Android架构组件——Jetpack,在现代Android开发中的应用。Jetpack作为一系列库和工具的集合,旨在帮助开发者更轻松地编写出健壮、可维护且性能优异的应用。通过详细解析各个组件如Lifecycle、ViewModel、LiveData等,我们将了解其原理和使用场景,并结合实例展示如何在实际项目中应用这些组件,提升开发效率和应用质量。
55 6
|
4月前
|
编译器 Android开发 开发者
带你了解Android Jetpack库中的依赖注入框架:Hilt
本文介绍了Hilt,这是Google为Android开发的依赖注入框架,基于Dagger构建,旨在简化依赖注入过程。Hilt通过自动化的组件和注解减少了DI的样板代码,提高了应用的可测试性和可维护性。文章详细讲解了Hilt的主要概念、基本用法及原理,帮助开发者更好地理解和应用Hilt。
101 8
|
4月前
|
安全 Java Android开发
探索安卓应用开发的新趋势:Kotlin和Jetpack Compose
在安卓应用开发领域,随着技术的不断进步,新的编程语言和框架层出不穷。Kotlin作为一种现代的编程语言,因其简洁性和高效性正逐渐取代Java成为安卓开发的首选语言。同时,Jetpack Compose作为一个新的UI工具包,提供了一种声明式的UI设计方法,使得界面编写更加直观和灵活。本文将深入探讨Kotlin和Jetpack Compose的特点、优势以及如何结合使用它们来构建现代化的安卓应用。
98 4
|
6月前
|
存储 数据库 Android开发
🔥Android Jetpack全解析!拥抱Google官方库,让你的开发之旅更加顺畅无阻!🚀
【7月更文挑战第28天】在Android开发中追求高效稳定的路径?Android Jetpack作为Google官方库集合,是你的理想选择。它包含多个独立又协同工作的库,覆盖UI到安全性等多个领域,旨在减少样板代码,提高开发效率与应用质量。Jetpack核心组件如LiveData、ViewModel、Room等简化了数据绑定、状态保存及数据库操作。引入Jetpack只需在`build.gradle`中添加依赖。例如,使用Room进行数据库操作变得异常简单,从定义实体到实现CRUD操作,一切尽在掌握之中。拥抱Jetpack,提升开发效率,构建高质量应用!
100 4
|
6月前
|
存储 移动开发 Android开发
使用kotlin Jetpack Compose框架开发安卓app, webview中h5如何访问手机存储上传文件
在Kotlin和Jetpack Compose中,集成WebView以支持HTML5页面访问手机存储及上传音频文件涉及关键步骤:1) 添加`READ_EXTERNAL_STORAGE`和`WRITE_EXTERNAL_STORAGE`权限,考虑Android 11的分区存储;2) 配置WebView允许JavaScript和文件访问,启用`javaScriptEnabled`、`allowFileAccess`等设置;3) HTML5页面使用`<input type="file">`让用户选择文件,利用File API;
|
7月前
|
安全 JavaScript 前端开发
kotlin开发安卓app,JetPack Compose框架,给webview新增一个按钮,点击刷新网页
在Kotlin中开发Android应用,使用Jetpack Compose框架时,可以通过添加一个按钮到TopAppBar来实现WebView页面的刷新功能。按钮位于右上角,点击后调用`webViewState?.reload()`来刷新网页内容。以下是代码摘要:
|
6月前
|
Android开发
Android kernel 操作gpio
Android kernel 操作gpio
68 0
|
7月前
|
Android开发
Jetpack Compose: Hello Android
Jetpack Compose: Hello Android
|
7月前
|
存储 算法 Java
Android 进阶——代码插桩必知必会&ASM7字节码操作
Android 进阶——代码插桩必知必会&ASM7字节码操作
325 0