首页 > 解决方案 > 如何在没有BottomNavigationView的情况下使用BottomNavigationView和内部屏幕实现带有少量片段的Single Activity?

问题描述

我想实现具有BottomNavigationView(3 个选项卡)的主屏幕的导航,并且从选项卡屏幕到它将移动到没有BottomNavigationView.

这可以通过使用经典片段导航而不使用 Android Jetpack 来实现。但是使用 JetPack 我无法找到正确的方法。

我已经尝试通过显示/隐藏BottomNavigationView使用addOnDestinationChangedListener,但如果从不同的选项卡打开相同的屏幕,我的导航图似乎不正确。

想要实现使用NavigatinoGraph

流动 :

Home(Tab1) >> Product Details(Without Tab) >> Production Photos(Without Tab) >> ...

Account(Tab2) >> Partners List(Without Tab) >> Partener Details(Without Tab) >> ...
              >> Retailer List(Without Tab) >> Retailer Details(Without Tab) >> ...
              >> Wholesaler List(Without Tab) >> Wholesaler Details(Without Tab) >> ...


Settings(Tab2) >> Change Password(Without Tab) >> OTP(Without Tab) >> Success Screen(WithoutTab)

每个选项卡的主屏幕都有多个菜单,应该转到没有BottomNavigationView.

我已经检查了导航视图的其他示例和扩展功能,但其中大多数也类似于内部屏幕的 BottomNavigationView。

任何人都可以建议我如何使用 Single Activity & without Showing & hidden 来实现BottomNavigationView。?

标签: androidandroid-fragmentsandroid-jetpackandroid-jetpack-navigationandroid-navigation-graph

解决方案


仅在将 Home/Account/Settings 作为子片段托管的 RootFragment 中使用 BottomNavigationView

class RootFragment : Fragment(R.layout.root_fragment) {
    private val binding by viewBinding(RootFragmentBinding::bind)

    private lateinit var firstFragment: HomeFragment
    private lateinit var secondFragment: AccountFragment
    private lateinit var thirdFragment: SettingsFragment

    private val fragments: Array<Fragment> get() = arrayOf(firstFragment, secondFragment, thirdFragment)
    private var selectedIndex = 0

    private val tabs: Array<TextView>
        get() = binding.run {
            arrayOf(buttonFirstTab, buttonSecondTab, buttonThirdTab)
        }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        if (savedInstanceState == null) {
            val firstFragment = HomeFragment().also { this.firstFragment = it }
            val secondFragment = AccountFragment().also { this.secondFragment = it }
            val thirdFragment = SettingsFragment().also { this.thirdFragment = it }

            childFragmentManager.beginTransaction()
                .add(R.id.containerBottomNavContent, firstFragment, "firstFragment")
                .add(R.id.containerBottomNavContent, secondFragment, "secondFragment")
                .add(R.id.containerBottomNavContent, thirdFragment, "thirdFragment")
                .selectFragment(selectedIndex)
                .commit()
        } else {
            selectedIndex = savedInstanceState.getInt("selectedIndex", 0)

            firstFragment = childFragmentManager.findFragmentByTag("firstFragment") as HomeFragment
            secondFragment = childFragmentManager.findFragmentByTag("secondFragment") as AccountFragment
            thirdFragment = childFragmentManager.findFragmentByTag("thirdFragment") as SettingsFragment
        }
    }

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

        tabs.forEachIndexed { index, textView ->
            textView.setOnClickListener {
                selectFragment(index)
            }
        }

        setupTabSelectedState(selectedIndex)
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        outState.putInt("selectedIndex", selectedIndex)
    }

    private fun FragmentTransaction.selectFragment(selectedIndex: Int): FragmentTransaction {
        fragments.forEachIndexed { index, fragment ->
            if (index == selectedIndex) {
                attach(fragment)
            } else {
                detach(fragment)
            }
        }

        setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)

        return this
    }

    private fun setupTabSelectedState(selectedIndex: Int) {
        tabs.forEachIndexed { index, textView ->
            textView.setTextColor(when {
                index == selectedIndex -> ContextCompat.getColor(requireContext(), R.color.tab_selected)
                else -> ContextCompat.getColor(requireContext(), R.color.tab_unselected)
            })
        }
    }

    private fun selectFragment(indexToSelect: Int) {
        this.selectedIndex = indexToSelect

        setupTabSelectedState(indexToSelect)

        childFragmentManager.beginTransaction()
            .selectFragment(indexToSelect)
            .commit()
    }
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/rootContainer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/containerBottomNavContent"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="#EFEFEF" />

    <LinearLayout
        android:id="@+id/containerBottomNavItems"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/buttonFirstTab"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:clickable="true"
            android:focusable="true"
            android:foreground="?android:attr/selectableItemBackground"
            android:gravity="center"
            android:padding="16dp"
            android:text="First Tab"
            tools:textColor="@color/tab_selected" />

        <TextView
            android:id="@+id/buttonSecondTab"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:clickable="true"
            android:focusable="true"
            android:foreground="?android:attr/selectableItemBackground"
            android:gravity="center"
            android:padding="16dp"
            android:text="Second Tab"
            tools:textColor="@color/tab_unselected" />

        <TextView
            android:id="@+id/buttonThirdTab"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:clickable="true"
            android:focusable="true"
            android:foreground="?android:attr/selectableItemBackground"
            android:gravity="center"
            android:padding="16dp"
            android:text="Third Tab"
            tools:textColor="@color/tab_unselected" />
    </LinearLayout>
</LinearLayout>

推荐阅读