Problem
I have an activity_main.xml
that contains multiple fragments
. 1 of the fragment
is a bottom_menu_bar
that has 2 buttons which I would like the app to navigate to upon clicking.
However, I am not sure what is the proper way of hooking up the navController
. Should this be done via MainActivity.kt
or through FragmentBottomMainMenu.ktv
(where the bottom menu bar fragment is created in)
Note : As per android's specification, I am using databinding
and not findViewById
.
activity_main.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<fragment
android:id="@+id/navigation_graph_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:defaultNavHost="true"
app:navGraph="@navigation/navigation_graph" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/Fragment_Bottom_Main_Menu_hosted_in_activity_main"
android:name="com.createdlesson.lesson1.FragmentBottomMainMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main) // hooking up xml to DataBinding
//This is just a test. ignore this please.
//binding.apply {
// testText.text = "overwrite text Here"
//}
}
}
Fragment_bottom_main_menu.xml
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmentBottomMainMenu">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/fragment_bottom_main_menu_items_container"
android:layout_height="match_parent"
android:layout_width="wrap_content"
app:backgroundTint="@color/colorPrimary"
app:menu="@menu/fragment_bottom_main_menu_items" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</FrameLayout>
</layout>
FragmentBottomMainMenu.kt -> This is where I think NavController
should be instantiated and hooked up... But i'm not sure if this is correct, or how that should be done properly
class FragmentBottomMainMenu : Fragment() {
private lateinit var binding: FragmentBottomMainMenuBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
Log.i("FragBotMainMenu", "Inflating bottom main menu")
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_bottom_main_menu, container, false)
binding.fragmentBottomMainMenuItemsContainer.setOnNavigationItemSelectedListener {
when(it.itemId){
R.id.item1-> {
view?.findNavController()?.navigate(R.id.action_fragmentBottomMainMenu_to_fragmentItem1)
println("Navigated to item1")
return@setOnNavigationItemSelectedListener true
}
R.id.item2-> {
view?.findNavController()?.navigate(R.id.action_fragmentBottomMainMenu_to_fragmentItem2)
println("Navigated to item2")
return@setOnNavigationItemSelectedListener true
}
else -> {
println("${it.title}")
return@setOnNavigationItemSelectedListener true
}
}
}
return binding.root
}
}
fragment_bottom_main_menu_items.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/item1"
android:title="item no 1"/>
<item
android:id="@+id/item2"
android:title="item no 2"/>
</menu>
navigation_graph.xml
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/navigation_graph"
app:startDestination="@id/fragmentBottomMainMenu">
<fragment
android:id="@+id/fragmentBottomMainMenu"
android:name="com.createdlesson.lesson1.FragmentBottomMainMenu"
android:label="FragmentBottomMainMenu" >
<action
android:id="@+id/action_fragmentBottomMainMenu_to_fragmentItem1"
app:destination="@id/fragmentItem1" />
<action
android:id="@+id/action_fragmentBottomMainMenu_to_fragmentItem2"
app:destination="@id/fragmentItem2" />
</fragment>
<fragment
android:id="@+id/fragmentItem1"
android:name="com.createdlesson.lesson1.FragmentItem1"
android:label="fragment_item1"
tools:layout="@layout/fragment_item1"/>
<fragment
android:id="@+id/fragmentItem2"
android:name="com.createdlesson.lesson1.FragmentItem2"
android:label="FragmentItem2"
tools:layout="@layout/fragment_item2"/>
</navigation>
As for the .kt
and xml
files for Item1
and Item2
, they are simply a new fragment .kt
and xml
file right now. the xml
has a layout
tag, and the .kt
file has databinding
hooked up to it. thats about it
I would suggest using this patters which is simple and easy to implements: In your activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".uiHost.MainActivity">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_home"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="false"
app:layout_constraintBottom_toTopOf="@+id/bottom_nav_home"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0"
app:navGraph="@navigation/navigation_home" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_nav_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:menu="@menu/bottom_nav_home" />
</androidx.constraintlayout.widget.ConstraintLayout>
The code to hookUp the botttomNavigation in MainActivity.kt
val navController = childFragmentManager.findFragmentById(R.id.nav_host_home)
mBinding.bottomNavHome.setupWithNavController(navController = navController!!.findNavController())
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.