首页 > 解决方案 > 导航组件以编程方式设置过渡动画

问题描述

昨天我遇到了一个问题,我需要在我的 baseFragment 中从 nav_graph.xml 设置动画,并以编程方式从当前节点获取动作对象,其中包括 enterAnim 和 exitAnim 资源。在这里找不到解决方案,所以我们开始吧。

首先,我们需要将 res 文件夹中的动画提供给 anim 文件夹,因为它很饿。

slide_in_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="250"
        android:fromXDelta="-100%"
        android:fromYDelta="0%"
        android:toXDelta="0%"
        android:toYDelta="0%" />
</set>

您可以在 github 或 stackoverflow 上轻松找到其他动画。

这是我的 nav_graph.xml 片段,我们将从中进行转换

<fragment
    android:id="@+id/kebabsFragment"
    android:name="com.kebabkrabby.kebabapp.KebabFragment"
    android:label="so many kebabs"
    tools:layout="@layout/fragment_kebab">

    <action
        android:id="@+id/action_kebabs_to_kebab_detail"
        app:destination="@id/kebabDetailFragment"
        app:enterAnim="@anim/slide_in_right"
        app:exitAnim="@anim/slide_out_left" />
</fragment>

现在在 KebabFragment.tk 中,你将调用 baseFragment 方法进行转换,以了解我们想要的烤肉串的细节,然后 popFromBackStack

//navigateAndClean(actionId, cleanFragmentId)
navigateAndClean(R.id.action_kebabs_to_kebab_detail, R.id.kebabsFragment)

在我们的 baseFragment.kt

internal fun navigateAndClean(actionId: Int, currentFragmentIdToClear: Int) {

    val navBuilder = NavOptions.Builder()

    val navController = Navigation.findNavController(getRootView())
    val currNavigationNode = navController.graph.findNode(currentFragmentIdToClear) // NavDestination of kebabsFragment object in nav_graph.xml
    val action = currNavigationNode?.getAction(actionId) // finally we get this action_kebabs_to_kebab_detail action object

    action?.navOptions?.enterAnim?.let {  //do we have animation or not?
        navBuilder.setEnterAnim(it)
    }

    action?.navOptions?.exitAnim?.let {
        navBuilder.setExitAnim(it)
    }

    navBuilder.setPopUpTo(currentFragmentIdToClear, true)       //remove from backstack

    navController.navigate(actionId, null, navBuilder.build())
}

有些人会问。嘿,Kebab 先生,但我怎么能得到getRootView() ,Kebab 先生会看着你说“伙计,看看这个世界,我们可以一起成就大事”

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    rootView = inflater.inflate(mContentLayoutResourceId, container, false)
    return rootView
}

fun getRootView(): View {
    return rootView
}

杜伦烤肉串。享受。

标签: android-fragmentskotlinandroid-animationandroid-architecture-componentsandroid-architecture-navigation

解决方案


推荐阅读