如何判断片段在 N​​avigationDrawer 中何时不可见

Posted

技术标签:

【中文标题】如何判断片段在 N​​avigationDrawer 中何时不可见【英文标题】:How to tell when fragment is not visible in a NavigationDrawer 【发布时间】:2017-12-29 08:46:35 【问题描述】:

我试图判断用户何时在我的导航抽屉中选择了不同的片段。我正在尝试使用

override fun setUserVisibleHint(isVisibleToUser: Boolean) 
    super.setUserVisibleHint(isVisibleToUser)

我如何在 MainActivity 中切换片段:

override fun onNavigationItemSelected(item: MenuItem): Boolean 
        // Handle navigation view item clicks here.
        when (item.itemId) 

            R.id.nav_camera -> 
                // Handle the camera action
                val fragment: HomeFragment = HomeFragment()
                supportFragmentManager.beginTransaction().replace(R.id.content_main, fragment).commit()

            
            R.id.nav_manage -> 
                val fragment: SettingFragment = SettingFragment()
                fragmentManager.beginTransaction().replace(R.id.content_main, fragment).commit()

            
            R.id.nav_share -> 
                onInviteClicked()

            
            R.id.nav_send -> 

                val emailIntent: Intent = Intent(android.content.Intent.ACTION_SEND)
                emailIntent.type = Constants.FEEDBACK_EMAIL_TYPE

                emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
                        arrayOf(Constants.FEEDBACK_EMAIL_ADDRESS))

                emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
                        Constants.FEEDBACK_EMAIL_SUBJECT)

                startActivity(Intent.createChooser(
                        emailIntent, Constants.FEEDBACK_TITLE))


            
        

        val drawer: DrawerLayout = findViewById(R.id.drawer_layout)
        drawer.closeDrawer(GravityCompat.START)
        return true
    

但是,这似乎根本没有被调用。例如,在我的NavigationDrawer 活动中,它显示片段 A。用户打开导航抽屉并选择片段 B。setUserVisibleHint() 不会在片段 A 中被调用,因此我的代码可以知道它不再显示。我需要在片段 A 中隔离的代码知道何时未显示它,以便它可以在某些变量上调用 .stop() 。这与活动中的 onPause() 用例相同。

【问题讨论】:

我不明白你的问题。为什么不直接使用导航抽屉?我的意思是,你知道用户选择了片段 B,所以你知道发生了什么。那么什么不应该把你的逻辑放在 Navigation Drawer 的 onClickListener 中。就像这样,您无需尝试从 Fragment 的状态猜测它就可以知道显示或不显示什么。但是你确定你的 Fragment A 没有显示 btw 吗?你能得到导航抽屉监听器的代码吗? 请贴更多代码,你在哪里调用这个函数?你的活动是什么样的? @Eselfar 我已经添加了更多关于为什么我需要它的信息。 那么为什么不在 Fragment 的 onPause 中调用 .stop 呢?还是不明白你的问题。 如何切换片段? 【参考方案1】:

你可以简单地调用

if (myFragment.isVisible()) ...

或者另一种方式是

public boolean isFragmentUIActive() 
    return isAdded() && !isDetached() && !isRemoving();

【讨论】:

由于这不是一个被覆盖的方法,我必须有一个无限循环不断检查片段是否可见,这并不理想。【参考方案2】:

这是我能想到的一些事情......

    使用一致的片段,支持或本机,而不是两者。而且,有人说支持片段更可取(维护得更好)。 确保片段容器未在 XML 中硬编码。如果您打算替换片段,则初始片段应由您的代码动态加载(您通常会使用 id 作为 R.id.frameLayoutId 加载到 FrameLayout)。 使用 Frament 生命周期事件。 onPause 在替换片段时触发,onDetach 也是如此。这将告诉您您的旧片段何时不再可见(或很快将不可见)。如果它没有触发,那么您的代码中还有另一个问题,可能是 Fragment 类型的混合,或者 XML 中的硬编码片段? 仅在片段寻呼机中使用setUserVisibleHint,或者准备手动设置它。 this 回答对setUserVisibleHint 的使用还有一点要说的。使用寻呼机时,可以同时附加多个片段,因此需要一种额外的方法(有人称之为生命周期事件)来判断片段是否“真正、真正”可见,因此引入了setUserVisibleHint

    奖励:如果适用于您的应用,请在replace 之后调用addToBackStack 来使用后台堆栈进行备份。我主要将其添加为人们通常希望在他们的应用程序中添加的生命周期项目。代码长这样……

    // to initialize your fragment container
    supportFragmentManager
            .beginTransaction()
            .add(R.id.content_fragment, fragment)
            .addToBackStack("blank")
            .commit()
    
    // to update your fragment container
    supportFragmentManager
            .beginTransaction()
            .replace(R.id.content_fragment, fragment)
            .addToBackStack("settings")
            .commit()
    
    //in your XML, it can be as simple as adding the FrameLayout below,
    // if you start with the Android Studio template for Navigation drawer,
    // you can replace the call that includes the "content_main" layout
    
    <!--<include layout="@layout/content_main" /> -->
    <FrameLayout
        android:layout_
        android:layout_
        android:id="@+id/content_fragment" />
    

我希望这会有所帮助。

【讨论】:

我会特别添加使用 PreferenceFragmentCompat 与 supportfragmentmanager 一起使用。这是问题,因为我同时使用本机和支持片段管理器

以上是关于如何判断片段在 N​​avigationDrawer 中何时不可见的主要内容,如果未能解决你的问题,请参考以下文章

Android:更换片段时如何停止音乐?

如何在android tv中使用像netflix这样的浏览片段制作侧边菜单?

如何在 C++ 中为 GLSL 片段着色器实现 iGlobalTime?

如何在 Android Volley 中判断 TLS 版本

条件片段和导航重用

谷歌地图片段在 N​​estedScrollView 内滚动