繁体   English   中英

从不在 backstack 顶部的 backstack 中删除特定片段

[英]Remove specefic fragment from backstack that is not on top of backstack

精简版:

我通过替换方法( A -> B -> C -> D -> E )将 5 个片段全部添加到容器中,现在我想从我的 backStack(C) 中删除 3rdfragment 并留在当前页面,怎么办它?

问题:

我有 3 个片段, FragmentAFragmentBFragmentC ,用户从A to B then C导航A to B then C 在 FragmentC 中,当用户执行一个操作(我称之为ActionX )时,我需要从我的片段管理器BackStack删除FragmentB (而用户仍然在 FragmentC 中)并且我不希望用户注意到任何事情,只是当他按下手机不同时片段显示(因此,如果用户按下时发生 ActionX,则片段 A 显示,如果不显示 FragmentB)

这就是我显示fragments (我为名称和标签设置片段名称以在需要时找到它们)

public void showFragment(Fragment fragment) {
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        String tag = fragment.getClass().getSimpleName();
        fragmentTransaction.replace(R.id.fragment_container, fragment, tag);
        fragmentTransaction.addToBackStack(tag);
        fragmentTransaction.commit();
}

我尝试了一些 SO 线程中提到的解决方案(像这样),但它们只适用于堆栈中的顶部片段,或者他们建议不要使用 FragmentB(我不能这样做,因为我不知道用户会做什么),还从堆栈中查找和删除 FragmentB不起作用。 一种解决方案是覆盖我的 Activity 的 onBackPressed 并检查 ActionX 是否发生并两次弹出我的 backStack。

我试过的:

  1. 这不起作用(fragmentBInStack 不为​​空,但是当我删除它时什么也没有发生)
val fragmentBInStack = manager.findFragmentByTag(FragmentB::class.java.simpleName)
fragmentBInStack?.let {
    manager.beginTransaction().remove(it).commit()
}
  1. 此代码删除FragmentC和FragmentB和表演FragmentA都(我想留在FragmentC),如果我的用户0的instad POP_BACK_STACK_INCLUSIVE只弹出FragmentC和表演FragmentB
manager.popBackStack(FragmentB::class.java.simpleName, FragmentManager.POP_BACK_STACK_INCLUSIVE)

这是我想要做的一些示例代码

class FragmentC : Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        view.findViewById<View>(R.id.action_x).setOnClickListener {

            //here I want to remove FragmentB from back Stack and stay in FragmentC, just later when user presses back I want to show FragmentA
            val manager = activity!!.supportFragmentManager
            val fragmentBInStack = manager.findFragmentByTag(FragmentB::class.java.simpleName)
            fragmentBInStack?.let {
                manager.beginTransaction().remove(it).commit()
            }
        }
    }

好的,首先,您必须在单独的事务中添加片段,并将replace更改为add

supportFragmentManager
    .beginTransaction()
    .add(R.id.fragment_container, fragment2, tag2)
    .addToBackStack(tag2)
    .commit()

然后你像你一样删除片段:

val fragment2 = supportFragmentManager.findFragmentByTag(tag2)!!
supportFragmentManager.beginTransaction().remove(fragment2).commit()

最后一步就是popBackStack:

supportFragmentManager.popBackStack()

我可以建议以下方法:使用相同的ViewModel实例(使用ViewModelProvider的活动来创建视图模型实例)与FragmentBFragmentC ActionX 事件LiveData FragmentC中设置了LiveData的值,而FragmentB观察实时数据变化。

这是源代码。

1.查看模型

class InterFragmentViewModel : ViewModel() {
    val actionXLiveData = MutableLiveData<Boolean>()
}

2.片段C

class FragmentC : AppCompatDialogFragment() {

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        view.findViewById<View>(R.id.action_x).setOnClickListener {
            ViewModelProvider(requireActivity()).get(InterFragmentViewModel::class.java)
                .actionXLiveData.value = true
        }
    }
}

3.片段B

class FragmentB : AppCompatDialogFragment() {

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        ViewModelProvider(requireActivity()).get(InterFragmentViewModel::class.java)
            .actionXLiveData.observe(viewLifecycleOwner, Observer {
            parentFragmentManager.popBackStack()
        })

    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM