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



相关文章
|
2月前
|
存储 Shell Android开发
基于Android P,自定义Android开机动画的方法
本文详细介绍了基于Android P系统自定义开机动画的步骤,包括动画文件结构、脚本编写、ZIP打包方法以及如何将自定义动画集成到AOSP源码中。
47 2
基于Android P,自定义Android开机动画的方法
|
12天前
|
存储 开发框架 数据可视化
深入解析Android应用开发中的四大核心组件
本文将探讨Android开发中的四大核心组件——Activity、Service、BroadcastReceiver和ContentProvider。我们将深入了解每个组件的定义、作用、使用方法及它们之间的交互方式,以帮助开发者更好地理解和应用这些组件,提升Android应用开发的能力和效率。
|
25天前
|
编译器 Android开发 开发者
带你了解Android Jetpack库中的依赖注入框架:Hilt
本文介绍了Hilt,这是Google为Android开发的依赖注入框架,基于Dagger构建,旨在简化依赖注入过程。Hilt通过自动化的组件和注解减少了DI的样板代码,提高了应用的可测试性和可维护性。文章详细讲解了Hilt的主要概念、基本用法及原理,帮助开发者更好地理解和应用Hilt。
40 8
|
24天前
|
缓存 搜索推荐 Android开发
安卓应用开发中的自定义View组件实践
【9月更文挑战第10天】在安卓开发领域,自定义View是提升用户体验和实现界面个性化的重要手段。本文将通过一个实际案例,展示如何在安卓项目中创建和使用自定义View组件,包括设计思路、实现步骤以及可能遇到的问题和解决方案。文章不仅提供了代码示例,还深入探讨了自定义View的性能优化技巧,旨在帮助开发者更好地掌握这一技能。
|
26天前
|
安全 Java Android开发
探索安卓应用开发的新趋势:Kotlin和Jetpack Compose
在安卓应用开发领域,随着技术的不断进步,新的编程语言和框架层出不穷。Kotlin作为一种现代的编程语言,因其简洁性和高效性正逐渐取代Java成为安卓开发的首选语言。同时,Jetpack Compose作为一个新的UI工具包,提供了一种声明式的UI设计方法,使得界面编写更加直观和灵活。本文将深入探讨Kotlin和Jetpack Compose的特点、优势以及如何结合使用它们来构建现代化的安卓应用。
34 4
|
2月前
|
存储 搜索推荐 Java
探索安卓开发中的自定义视图:打造个性化UI组件Java中的异常处理:从基础到高级
【8月更文挑战第29天】在安卓应用的海洋中,一个独特的用户界面(UI)能让应用脱颖而出。自定义视图是实现这一目标的强大工具。本文将通过一个简单的自定义计数器视图示例,展示如何从零开始创建一个具有独特风格和功能的安卓UI组件,并讨论在此过程中涉及的设计原则、性能优化和兼容性问题。准备好让你的应用与众不同了吗?让我们开始吧!
|
2月前
|
XML 搜索推荐 Android开发
安卓开发中的自定义View组件实践
【8月更文挑战第30天】探索Android世界,自定义View是提升应用界面的关键。本文以简洁的语言带你了解如何创建自定义View,从基础到高级技巧,一步步打造个性化的UI组件。
|
3月前
|
存储 数据库 Android开发
🔥Android Jetpack全解析!拥抱Google官方库,让你的开发之旅更加顺畅无阻!🚀
【7月更文挑战第28天】在Android开发中追求高效稳定的路径?Android Jetpack作为Google官方库集合,是你的理想选择。它包含多个独立又协同工作的库,覆盖UI到安全性等多个领域,旨在减少样板代码,提高开发效率与应用质量。Jetpack核心组件如LiveData、ViewModel、Room等简化了数据绑定、状态保存及数据库操作。引入Jetpack只需在`build.gradle`中添加依赖。例如,使用Room进行数据库操作变得异常简单,从定义实体到实现CRUD操作,一切尽在掌握之中。拥抱Jetpack,提升开发效率,构建高质量应用!
53 4
|
2月前
|
开发工具 Android开发
Android项目架构设计问题之组件A通知组件B某个事件的发生如何解决
Android项目架构设计问题之组件A通知组件B某个事件的发生如何解决
32 0
|
3月前
|
机器学习/深度学习 人工智能 算法
探索AI在医疗影像分析中的应用探索安卓开发中的自定义View组件
【7月更文挑战第31天】随着人工智能技术的飞速发展,其在医疗健康领域的应用日益广泛。本文将聚焦于AI技术在医疗影像分析中的运用,探讨其如何通过深度学习模型提高诊断的准确性和效率。我们将介绍一些关键的深度学习算法,并通过实际代码示例展示这些算法是如何应用于医学影像的处理和分析中。文章旨在为读者提供对AI在医疗领域应用的深刻理解和实用知识。
35 0
下一篇
无影云桌面