【问题标题】:How to Listen to Transition Completed on Android Fragment Transition with Navigation Component?如何使用导航组件在 Android 片段转换上收听转换完成?
【发布时间】:2021-04-13 10:41:26
【问题描述】:

我有一个片段可以加载大量数据并将其显示到 recyclerView 中。如果我直接打开此片段而不等待转换完成,则转换将变得不稳定,因为线程被 recyclerView 更新数据限制

所以我想延迟这个更新数据,直到片段转换完成。

但遗憾的是我还没有找到任何方法来收听片段转换完成,所以我目前的方法是将数据更新延迟几毫秒,直到使用 Handler() ,但我相信这是非常hacky而不是优雅的解决方案

Handler().postDelayed({
//do something
}, 500)

我需要帮助才能知道我应该调用什么方法来收听片段转换完成。谢谢你哦

【问题讨论】:

    标签: android kotlin android-fragments android-transitions


    【解决方案1】:

    片段提供了两种避免此问题的方法:

    1. postponing your transition 加载数据之前,您可以避免开始转换。这可确保您的 RecyclerView 已填充可用于共享元素转换等的数据。这是一般建议,可确保在所有版本的 Fragments 上顺利转换。

    2. 当使用Fragment 1.3.0 或更高版本时,您的片段将不会达到恢复状态,直到任何过渡或动画器(尤其不是动画)完成。这使您可以使用onResume() 作为转换完成的信号。

    【讨论】:

    • 嗨,伊恩!我正在使用片段1.3.1onResume() 似乎在navigate() 之后被调用。我也试过使用版本1.3.0,但也没有用。
    • 那么你在使用动画师吗?动画?框架过渡? AndroidX 过渡?如果是最后一个,什么版本的 AndroidX 转换?确保您使用的是最新版本 (Transition 1.4.1)。
    • 我正在使用带有 Android 导航组件的自定义滑动动画。
    • 正如我在回答中非常明确地提到的,动画是onResume() 时间的一个例外(您是否考虑过使用Slide Transition?)。推迟适用于任何效果时间,包括动画,并允许您在开始动画之前完全加载数据。这就是为什么首先提到这种方法:-)
    • 感谢您澄清 :-)
    【解决方案2】:

    嗯,我在 this answer 之后使用 onCreateAnimation 做到了这一点

    override fun onCreateAnimation(transit: Int, enter: Boolean, nextAnim: Int): Animation? {
        val anim: Animation = AnimationUtils.loadAnimation(activity, nextAnim)
        anim.setAnimationListener(object : Animation.AnimationListener {
            override fun onAnimationStart(animation: Animation?) {}
            override fun onAnimationRepeat(animation: Animation?) {}
            override fun onAnimationEnd(animation: Animation?) {
                if (enter) {
                    //load and update recyclerView here
                }
            }
        })
        return anim
    }
    

    【讨论】:

    • 我不确定我是否理解这个问题,但是我们可以使用计时器而不是延迟吗?
    • @Furkan 计时器/延迟等问题是当我更改过渡持续时间时,它会中断并且屏幕再次变得迟钝。我需要确保过渡保持平稳,但我会调整值
    【解决方案3】:

    如果你必须使用动画,而不是过渡或动画,你可以将动画持续时间提取到一个整数资源中,并将动画持续时间设置为它:

    <!-- values/durations.xml -->
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <integer name="animation_duration">220</integer>
    </resources>
    
    
    <!-- anim/transition.xml -->
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
        android:shareInterpolator="false" >
        <alpha android:duration="@integer/animation_duration" android:fromAlpha="0.0" android:toAlpha="1.0" />
    </set>
    

    然后在你的片段中检索它:

    val animationDuration = requireContext().resources.getInteger(R.integer.animation_duration)
    Handler().postDelayed({
    //do something
    }, animationDuration)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 2021-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多