在Fragment中隐藏底部导航栏视图

6
我想在一些片段中隐藏bottomNavigationView。
我尝试了下面的代码,但它会产生闪烁效果。(bottomNavigationView在下一个片段变得可见之前就被隐藏了。)
    val navController = this.findNavController(R.id.nav_host_home)
    navController.addOnDestinationChangedListener { _, destination, _ ->
    when (destination.id) {
        R.id.searchArticlesFragment -> bnvMain.visibility = View.GONE
        R.id.articleFragment -> bnvMain.visibility = View.GONE
            else -> bnvMain.visibility = View.VISIBLE
        }
    }

我也尝试了另一段代码,但它调整了片段大小,并在目标片段中产生了OutOfMemoryException。

    supportFragmentManager.registerFragmentLifecycleCallbacks(object :
        FragmentManager.FragmentLifecycleCallbacks() {
        override fun onFragmentViewCreated(
            fm: FragmentManager,
            f: Fragment,
            v: View,
            savedInstanceState: Bundle?
        ) {
            when (f) {
                is SearchArticlesFragment -> bnvMain.visibility = View.GONE
                is ArticleDetailsFragment -> bnvMain.visibility = View.GONE
                else -> bnvMain.visibility = View.VISIBLE
            }
        }
    }, true)

请帮我找到最好的方法来隐藏bottomNavigationView?这是唯一可以隐藏bottomNavigationView的方式吗?Youtube和Instagram是如何实现此行为的?

1个回答

12

如果您的代码遵循单活动设计模式,则以下解决方案适合您。

  1. 在父活动中创建一个方法来隐藏/显示bottomNavigationView。
  2. 创建一个BaseFragment类(通过扩展此BaseFragment类来创建您的片段)
  3. 在BaseFragment中创建一个变量来保存bottomNavigationView的可见性(隐藏/显示)
  4. 在BaseFragment的onActivityCreated方法中,获取活动引用并调用我们在STEP1中创建的方法来设置bottomNavigationViewVisibility。
  5. 在您创建的每个片段中,只需设置bottomNavigationViewVisibility变量即可。

例如:在parentActivity布局文件中添加bottomNavigationView。

        <com.google.android.material.bottomnavigation.BottomNavigationView
            android:id="@+id/main_bottom_navigation_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?android:attr/windowBackground"
            app:labelVisibilityMode="labeled"
            app:menu="@menu/main_nav" />

步骤1:在父活动中创建一个方法来更改可见性。

 fun setBottomNavigationVisibility(visibility: Int) {
        // get the reference of the bottomNavigationView and set the visibility.
        activityMainBinding.mainBottomNavigationView.visibility = visibility
    }

第二步&第三步&第四步:

    abstract class BaseFragment : Fragment() {
    
        protected open var bottomNavigationViewVisibility = View.VISIBLE
    
        override fun onActivityCreated(savedInstanceState: Bundle?) {
            super.onActivityCreated(savedInstanceState)
            // get the reference of the parent activity and call the setBottomNavigationVisibility method.
            if (activity is MainActivity) {
               var  mainActivity = activity as MainActivity
                mainActivity.setBottomNavigationVisibility(bottomNavigationViewVisibility)
            }
        }
 override fun onResume() {
        super.onResume()
        if (activity is MainActivity) {
            mainActivity.setBottomNavigationVisibility(bottomNavigationViewVisibility)
        }
    }
    }

第五步:

class SampleFragment1 : BaseFragment() {

    // set the visibility here, it takes care of setting the bottomNavigationView.
    override var navigationVisibility = View.VISIBLE
    
   // override var navigationVisibility = View.GONE

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_sampleFragment1, container, false)
    }
}

1
非常感谢您的回答。这真的很有帮助,它像魔法一样运行!我必须提到的一件事是,我已经将onActivityCreated()方法更改为onStart(),因为当我返回到上一个片段时,onStart()是触发的方法(不知道为什么,但官方文档说onCreateView()会调用)。但我解决了我的问题。再次感谢您 :) - Milan Thakor
@MilanThakor,可以将它添加到onResume()而不是onStart()中。(注意:我已更新帖子以反映相同的内容)无论从哪个片段导航回来,都会调用onResume。至于你的第二个问题,当片段被创建时才会调用onCreateView(),在你的情况下,当你导航到下一个片段时,当前片段实例并没有完全销毁,而是被放置在后台堆栈中,当你点击返回时它会恢复。 - Manimaran Narasimman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接