gpt4 book ai didi

android - 从 LiveData 观察者调用时,导航组件默认返回堆栈不起作用

转载 作者:行者123 更新时间:2023-12-04 16:39:33 24 4
gpt4 key购买 nike

我正在使用带有抽屉导航的 Android Navigation 组件(如在 Android Studio 模板中)。我将 fragment A、B、C 作为用于抽屉导航的顶级 fragment 和与导航图中的 fragment A 连接的 fragment Z。现在我在 fragment A 中有一个按钮。单击该按钮将使用 Safe args 打开 fragment Z。

    binding.button.setOnClickListener {
val action = NewsFragmentDirections.actionNavNewsToNewsDetailsFragment()
it.findNavController().navigate(action)
}
当 fragment Z 打开时,应用栏图标将自动变为返回按钮,这将允许我返回 fragment A。
这些工作正常,但这个问题是,当我在实时数据观察者中使用相同的安全 args 代码时,后退按钮不起作用。
    viewModel.actionNewsDetails.observe(viewLifecycleOwner, {
val action = NewsFragmentDirections.actionNavNewsToNewsDetailsFragment()
findNavController().navigate(action)
})
这里有一些额外的细节
  • 一旦我们在 fragment Z 中,它将像往常一样显示返回导航,但仅单击它不会执行任何操作
  • 当我快速单击返回按钮几次时,我注意到应用栏标题闪烁(在 fragment A 和 Z 之间切换)
  • 当我在 fragment Z
  • 中时,我可以通过滑动打开抽屉导航
  • 我的实时数据代码写在 fragment A 的 onCreateView()
  • 实时数据由 ViewModel
  • 中的函数触发

    我一直在为这个问题苦苦挣扎。对不起,我的英语不好。

    最佳答案

    接下来的信息非常重要:

    When I clicked the back button fast for several time, I noticed the app bar title flickering (changing between fragment A and Z)


    我很确定会发生什么,您在 fragment Z 中的后退按钮工作正常,您的 fragment A 显示并且它的 liveData 再次被触发并再次导航到 fragment Z。这发生得非常快,但是正如您所指出的,当您这样做时非常快,您可以看到延迟。
    解决方案:在您的 LiveData 观察者中导航到 fragment Z 之前,更改 liveData 的值,这样当您返回 fragment A 时它不会再次触发。
    几周前,这个问题让我失去了一个小时。
    2020 年 10 月 26 日编辑 :
    要解决该问题,请实现 SingleLiveEvent类并使用它来代替 MutableLiveData .
    SingleLiveEvent.class
    /**
    * A lifecycle-aware observable that sends only new updates after subscription, used for events like
    * navigation and Snackbar messages.
    * <p>
    * This avoids a common problem with events: on configuration change (like rotation) an update
    * can be emitted if the observer is active. This LiveData only calls the observable if there's an
    * explicit call to setValue() or call().
    * <p>
    * Note that only one observer is going to be notified of changes.
    */
    public class SingleLiveEvent<T> extends MutableLiveData<T> {

    private static final String TAG = "SingleLiveEvent";

    private final AtomicBoolean mPending = new AtomicBoolean(false);

    @MainThread
    public void observe(LifecycleOwner owner, final Observer<? super T> observer) {

    if (hasActiveObservers()) {
    Log.w(TAG, "Multiple observers registered but only one will be notified of changes.");
    }

    // Observe the internal MutableLiveData
    super.observe(owner, new Observer<T>() {
    @Override
    public void onChanged(@Nullable T t) {
    if (mPending.compareAndSet(true, false)) {
    observer.onChanged(t);
    }
    }
    });
    }

    @MainThread
    public void setValue(@Nullable T t) {
    mPending.set(true);
    super.setValue(t);
    }

    /**
    * Used for cases where T is Void, to make calls cleaner.
    */
    @MainThread
    public void call() {
    setValue(null);
    }
    }
    Kotlin 版本
    class SingleLiveEvent<T> : MutableLiveData<T>() {
    val TAG: String = "SingleLiveEvent"

    private val mPending = AtomicBoolean(false)

    @MainThread
    override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {

    if (hasActiveObservers()) {
    Log.w(TAG,"Multiple observers registered but only one will be notified of changes.")
    }

    // Observe the internal MutableLiveData
    super.observe(owner, Observer<T> { t ->
    if (mPending.compareAndSet(true, false)) {
    observer.onChanged(t)
    }
    })
    }

    @MainThread
    override fun setValue(@Nullable t: T?) {
    mPending.set(true)
    super.setValue(t)
    }

    /**
    * Used for cases where T is Void, to make calls cleaner.
    */
    @MainThread
    fun call() {
    value = null
    }
    }

    关于android - 从 LiveData 观察者调用时,导航组件默认返回堆栈不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64062367/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com