按一次返回按钮停留在同一个片段上,如果按两次,它将返回到上一个片段

Posted

技术标签:

【中文标题】按一次返回按钮停留在同一个片段上,如果按两次,它将返回到上一个片段【英文标题】:Pressing back button once stay on the same fragment, and if pressing twice, it will go back to previous fragment 【发布时间】:2021-06-17 08:37:53 【问题描述】:

我有以下代码

package com.example.covid19
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.add
import androidx.fragment.app.commit
import com.example.covid19.fragments.CountryListFragment
import com.example.covid19.fragments.CountryStatisticFragment
import com.example.covid19.fragments.onClickedListener


class MainActivity : AppCompatActivity(), onClickedListener 
   override fun onCreate(savedInstanceState: Bundle?) 
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
       //first time the app is launched
       if (savedInstanceState == null) 
           setCountryFragment()
       
   

   private fun setCountryFragment() 
       supportFragmentManager.commit 
           setReorderingAllowed(true)
           add<CountryListFragment>(R.id.fragment_container_view)
       
   

   private fun changeFragment(arg: String) 
       lateinit var nextFragment: Fragment
       val currentFragment: Fragment? =
           supportFragmentManager.findFragmentById(R.id.fragment_container_view)
       if (currentFragment != null && currentFragment is CountryListFragment) 
           nextFragment = CountryStatisticFragment.newInstance(arg)

        else 
           nextFragment = CountryListFragment.newInstance()

       
       supportFragmentManager.commit 
           setReorderingAllowed(true)
           replace(R.id.fragment_container_view, nextFragment)
           addToBackStack(null)
       
   
   override fun onItemClicked(arg: String) 
       changeFragment(arg)
   

当我按下第二个片段 CountryStatisticFragment 中的按钮时,它会闪烁并停留在同一个片段上。我必须按两次才能转到第一个片段! 要“修复”它,我必须添加以下代码

override fun onBackPressed() 
    if(supportFragmentManager.backStackEntryCount > 0) 
        supportFragmentManager.popBackStackImmediate()
        //this should not be needed, but pressing back one time, when being in CountryStatisticFragment leads to a transition to same fragment, CountryStatisticFragment
        super.onBackPressed()
     else 
        super.onBackPressed()
    

但是感觉这不是正确的处理方式。任何见过类似行为或可以看到我在做什么的人吗?

【问题讨论】:

你为什么在setFragmentA()中打电话给addToBackStack(null)?您添加的第一个片段不应该在后台堆栈中 没有帮助!我现在已经删除了。错误仍然存​​在。该错误仅在从 FragmentB 导航回来时发生,也在一个单独的“项目”上对其进行了测试,两个简单的片段只有一个文本视图在每个片段上工作。然而,在我的实际项目中,两个片段都有一个回收视图,它不起作用。该错误仍然出现。我怀疑这是一个框架问题? 【参考方案1】:
override fun onCreate(savedInstanceState: Bundle?) 
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    //first time the app is launched
    if (savedInstanceState == null) 
        setFragmentA()
    


private fun setFragmentA() 
    supportFragmentManager.commit 
        setReorderingAllowed(true)
        add<FragmentA>(R.id.fragment_container_view)
        addToBackStack(null) // DELETE THIS     

首先猜测是在setFragmentA 中调用addToBackStack(null)。这会将第一个片段添加到 backstack 中,因此您不会在按下返回时退出,而是弹出堆栈并最终处于奇怪的状态。

【讨论】:

没有帮助!我现在已经删除了。错误仍然存​​在。该错误仅在从 FragmentB 导航回来时发生,也在单独的“项目”上对其进行了测试,其中两个简单的片段只有一个文本视图,每个片段都有效。然而,在我的实际项目中,两个片段都有一个回收视图,它不起作用。该错误仍然出现。我怀疑这是一个框架问题? 这极不可能是“框架问题”——您可能有错误。发布更多代码,说明 Activity 和 Fragments 的完整工作示例。您可能从最初的问题中遗漏了一些重要的内容。 现在看线程开头的代码。是没有任何修改的原始代码!主要活动负责与片段交互!【参考方案2】:

这是我的活动的完整且准确的代码。

package com.example.covid19


import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.add
import androidx.fragment.app.commit
import com.example.covid19.fragments.CountryListFragment
import com.example.covid19.fragments.CountryStatisticFragment
import com.example.covid19.fragments.onClickedListener


class MainActivity : AppCompatActivity(), onClickedListener 
   override fun onCreate(savedInstanceState: Bundle?) 
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
       //first time the app is launched
       if (savedInstanceState == null) 
           setCountryFragment()
       
   

   private fun setCountryFragment() 
       supportFragmentManager.commit 
           setReorderingAllowed(true)
           add<CountryListFragment>(R.id.fragment_container_view)

       
   

   private fun changeFragment(arg: String) 
       lateinit var nextFragment: Fragment
       val currentFragment: Fragment? =
           supportFragmentManager.findFragmentById(R.id.fragment_container_view)
       if (currentFragment != null && currentFragment is CountryListFragment) 
           nextFragment = CountryStatisticFragment.newInstance(arg)

        else 
           nextFragment = CountryListFragment.newInstance()


       
       supportFragmentManager.commit 
           setReorderingAllowed(true)
           replace(R.id.fragment_container_view, nextFragment)
           addToBackStack(null)
       
   
   override fun onItemClicked(arg: String) 
       changeFragment(arg)
   

CountryListFragment 和 CountryListFragment 里面都有 recyclerviews。这只是我做的一个爱好项目,其他的都行!

【讨论】:

不要“回答”您自己的问题以添加更多信息 - 删除此问题并编辑您的实际问题,使其完整准确。 您要求更多代码。我附上了与片段交互发生的活动的完整代码!我将代码移动到线程的开头。

以上是关于按一次返回按钮停留在同一个片段上,如果按两次,它将返回到上一个片段的主要内容,如果未能解决你的问题,请参考以下文章

为啥我需要按两次后退按钮才能第一次关闭片段?

Android - VideoView 需要按两次 BACK 才能退出

必须按两次才能进行 Swift 3 按钮操作

ASP.NET 验证控件与防止按钮连按两次送出

在 WPF 富文本框中点击选项卡按钮时会发生啥?

如何防止活动在按下按钮时加载两次