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



相关文章
|
24天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
2月前
|
存储 Android开发 开发者
深入理解安卓应用开发的核心组件
【10月更文挑战第8天】探索Android应用开发的精髓,本文带你了解安卓核心组件的奥秘,包括Activity、Service、BroadcastReceiver和ContentProvider。我们将通过代码示例,揭示这些组件如何协同工作,构建出功能强大且响应迅速的应用程序。无论你是初学者还是资深开发者,这篇文章都将为你提供新的视角和深度知识。
|
2月前
|
数据可视化 Android开发 开发者
安卓应用开发中的自定义View组件
【10月更文挑战第5天】在安卓应用开发中,自定义View组件是提升用户交互体验的利器。本篇将深入探讨如何从零开始创建自定义View,包括设计理念、实现步骤以及性能优化技巧,帮助开发者打造流畅且富有创意的用户界面。
93 0
|
7天前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
2月前
|
Android开发 UED
Android 中加载 Gif 动画
【10月更文挑战第20天】加载 Gif 动画是 Android 开发中的一项重要技能。通过使用第三方库或自定义实现,可以方便地在应用中展示生动的 Gif 动画。在实际应用中,需要根据具体情况进行合理选择和优化,以确保用户体验和性能的平衡。可以通过不断的实践和探索,进一步掌握在 Android 中加载 Gif 动画的技巧和方法,为开发高质量的 Android 应用提供支持。
|
2月前
|
XML 前端开发 Java
安卓应用开发中的自定义View组件
【10月更文挑战第5天】自定义View是安卓应用开发的一块基石,它为开发者提供了无限的可能。通过掌握其原理和实现方法,可以创造出既美观又实用的用户界面。本文将引导你了解自定义View的创建过程,包括绘制技巧、事件处理以及性能优化等关键步骤。
|
2月前
|
测试技术 数据库 Android开发
深入解析Android架构组件——Jetpack的使用与实践
本文旨在探讨谷歌推出的Android架构组件——Jetpack,在现代Android开发中的应用。Jetpack作为一系列库和工具的集合,旨在帮助开发者更轻松地编写出健壮、可维护且性能优异的应用。通过详细解析各个组件如Lifecycle、ViewModel、LiveData等,我们将了解其原理和使用场景,并结合实例展示如何在实际项目中应用这些组件,提升开发效率和应用质量。
49 6
|
3月前
|
存储 开发框架 数据可视化
深入解析Android应用开发中的四大核心组件
本文将探讨Android开发中的四大核心组件——Activity、Service、BroadcastReceiver和ContentProvider。我们将深入了解每个组件的定义、作用、使用方法及它们之间的交互方式,以帮助开发者更好地理解和应用这些组件,提升Android应用开发的能力和效率。
241 5
|
3月前
|
缓存 搜索推荐 Android开发
安卓应用开发中的自定义View组件实践
【9月更文挑战第10天】在安卓开发领域,自定义View是提升用户体验和实现界面个性化的重要手段。本文将通过一个实际案例,展示如何在安卓项目中创建和使用自定义View组件,包括设计思路、实现步骤以及可能遇到的问题和解决方案。文章不仅提供了代码示例,还深入探讨了自定义View的性能优化技巧,旨在帮助开发者更好地掌握这一技能。