BottomNavigationView Isn't Showing on Emulator - android

I'm trying to setup a BottomNavigationView on my MainActivity, but it's only showing in my activity_main.xml and not the emulator. Should I be setting something up in my MainActivity.kt to make it visible on the emulator? Thanks!
// activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="?attr/actionBarSize">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/nav_view"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginStart="0dp"
android:layout_marginTop="0dp"
android:layout_marginEnd="0dp"
android:layout_marginBottom="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/bottom_nav_menu" >
</com.google.android.material.bottomnavigation.BottomNavigationView>
</RelativeLayout>
// MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
}
}
// Screenshots
Update
I'm having troubles getting my app to run on a device. Is it because I'm setting something wrong in my OnCreate?
// MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(setOf(R.layout.fragment_news_feed, R.layout.fragment_friends, R.layout.fragment_messaging, R.layout.fragment_notifications, R.layout.fragment_menu))
setupActionBarWithNavController(navController, appBarConfiguration)
bottomNavigationView.setupWithNavController(navController)
}

Just try this. works for me.
setContentView(R.layout.activity_main);
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main);
}
}

you should set up your menu in the onCrate.
Example:
val bottomNavigationView = findViewById<BottomNavigationView>(R.id.id_ your_bottomNavigationView)
val navController = findNavController(R.id.your_fragment)
val appBarConfiguration = AppBarConfiguration(setOf(R.id.your_fragment1, R.id.your_fragment2, R.id.your_fragment3, R.id.your_fragment4))
setupActionBarWithNavController(navController, appBarConfiguration)
bottomNavigationView.setupWithNavController(navController)

Call setContentView() in the onCreate Method.

Related

....... does not have a NavController set

When I go to fragmentr_bag using the frag function in mainActivity and then back to home_fragment
And when I want to click on the digital button to go to CategorymodeFragment, this problem occurs
java.lang.IllegalStateException: View android.widget.FrameLayout{dc05058 V.E...... ........ 0,0-1080,2063} does not have a NavController set
mainActivity:
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportActionBar?.hide()
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
try {
binding.re.setOnNavigationItemSelectedListener {
if (it.itemId == R.id.home) {
val fragment1 = homeFragment()
frag(fragment1)
} else if (it.itemId == R.id.bag) {
val fragment3 = bagFragment()
frag(fragment3)
} else if (it.itemId == R.id.person) {
val fragment2 = accontFragment()
frag(fragment2)
}
true
}
}catch (e: Throwable){
}
}
fun frag (fragment: Fragment) {
try {
val manager = supportFragmentManager
val tra = manager.beginTransaction()
tra.replace(R.id.fragmentContainerView, fragment)
tra.commit()
}catch (E:Throwable){}
}
}
homefragment:
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
binding.digital.setOnClickListener() {
Navigation.findNavController(it).navigate(
homeFragmentDirections.actionHomeFragmentToListFragment()
.setSenderCategory("electronics")
)
}
return binding.root
}
mainActivity.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">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/re"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:menu="#menu/menu" />
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fragmentContainerView"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/re"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/navigations" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
fragmenthome.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"
>
<data>
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="androidx.navigation.fragment.NavHostFragment"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.homeFragment">
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:text="clothing"
android:textColor="#000000"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="#+id/textView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/textView2"
app:layout_constraintTop_toBottomOf="#+id/mode" />
>
<androidx.viewpager.widget.ViewPager
android:id="#+id/viewPager2"
android:layout_width="409dp"
android:layout_height="188dp"
android:layout_marginStart="1dp"
android:layout_marginTop="1dp"
android:layout_marginEnd="1dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
</androidx.viewpager.widget.ViewPager>
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/digital"
android:layout_width="72dp"
android:layout_height="68dp"
android:layout_marginTop="50dp"
android:src="#drawable/digital"
app:civ_border_color="#color/black"
app:civ_border_width="1dp"
app:layout_constraintBottom_toBottomOf="#+id/mode"
app:layout_constraintEnd_toStartOf="#+id/mode"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="#+id/tahrir"
app:layout_constraintTop_toBottomOf="#+id/recyclerviewProducts/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</FrameLayout>
You need to use activity's navcontroller as navhost fragment is in activity. Library's findNavController() may not work if use FragmentContainerView or FrameLayout.You can try 2 things. You can use the below function in fragment.
If you have FragmentContainerView:
private fun findNavController():NavController? {
val navHostFragment = (requireActivity() as? MainActivity)?.supportFragmentManager?.findFragmentById(R.id.fragmentContainerView) as? NavHostFragment
return navHostFragment?.navController
}
2)You can make it as <fragment> in xml instead of FragmentContainerView and use below function to get NavController.
private fun findNavController() = (requireActivity() as? MainActivity)?.findNavController()
Usage:
binding.digital.setOnClickListener() {
findNavController()?.navigate(
homeFragmentDirections.actionHomeFragmentToListFragment()
.setSenderCategory("electronics")
)
}

Android Navigation Error: You must call setGraph() before calling getGraph()

I'm trying to make an memo app, and this is my first time with application programming.
When I tried to run the code on my device it just dies after showing the IntroActivity and the error log says: "You must call setGraph() before calling getGraph()"
Below is the code.
class ListActivity : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityListBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityListBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.toolbar)
val navController = findNavController(R.id.nav_host_fragment_content_list)
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
binding.fab.setOnClickListener { view ->
val intent=Intent(applicationContext, DetailActivity::class.java)
startActivity(intent)
}
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_content_list)
return navController.navigateUp(appBarConfiguration)
|| super.onSupportNavigateUp()
}
}
When I googled about this error there were only answers about androidx.navigation version 2.3.0-alpha2, so I checked my build.gradle.
I was using 2.5.0, the latest version.
How else can I solve this problem?
activity_list.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ListActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/Theme.DimoMemo.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/Theme.DimoMemo.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="#layout/content_list" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginEnd="#dimen/fab_margin"
android:layout_marginBottom="16dp"
app:srcCompat="#drawable/ic_add"
android:layout_marginRight="#dimen/fab_margin" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
content_list.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/contentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<fragment
android:id="#+id/nav_host_fragment_content_list"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp" />
</FrameLayout>
check if the layout contains:
app:navGraph="#navigation/nav_graph"
app:defaultNavHost="true"
your nav_host_fragment_content_list must look like:
<fragment
android:id="#+id/nav_host_fragment_content_list"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:navGraph="#navigation/your_nav_graph"
app:defaultNavHost="true" />
https://developer.android.com/guide/navigation/navigation-getting-started

MAPBOX: The map does not appear when I run the app with no errors (developing in Kotlin - for android - map in a fragment)

I am developing an app in Kotlin for android. I am adding Mapbox to this app.
In particular, I need to insert the Mapbox's map in FragmentHome.
The map needs to interact with other components, ad a navigation bar, and some buttons.
In the HostActivity I inserted
class HostActivity : AppCompatActivity() {
lateinit var googleSignInClient: GoogleSignInClient
private lateinit var navController: NavController
private val mAuth: FirebaseAuth = FirebaseAuth.getInstance()
private val db: FirebaseFirestore = FirebaseFirestore.getInstance()
private lateinit var drawerLayout: DrawerLayout
private lateinit var navViewBinding: DrawerHeaderLayoutBinding
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_host)
val toolbar = customToolbar
setSupportActionBar(toolbar)
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build()
googleSignInClient = GoogleSignIn.getClient(this, gso)
drawerLayout = drawer_layout
navViewBinding = DrawerHeaderLayoutBinding.inflate(layoutInflater, navView, true)
val navHost =
supportFragmentManager.findFragmentById(R.id.navHostFragment) as NavHostFragment
navController = navHost.navController
val navInflater = navController.navInflater
val graph = navInflater.inflate(R.navigation.main_graph)
navController.addOnDestinationChangedListener { _, destination, _ ->
if (destination.id == R.id.onBoarding ||
destination.id == R.id.authFragment ||
destination.id == R.id.loginFragment ||
destination.id == R.id.signUpFragment
) {
toolbar.visibility = View.GONE
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
} else {
toolbar.visibility = View.VISIBLE
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
}
}
if (!Prefs.getInstance(this)!!.hasCompletedWalkthrough!!) {
if (mAuth.currentUser == null) {
graph.startDestination = R.id.authFragment
} else {
getUserData()
graph.startDestination = R.id.homeFragment
}
} else {
graph.startDestination = R.id.onBoarding
}
navController.graph = graph
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
navView.setupWithNavController(navController)
navView.setNavigationItemSelectedListener {
it.isChecked
drawerLayout.closeDrawers()
when (it.itemId) {
R.id.action_logout -> {
MyApplication.currentUser!!.active = false
FirestoreUtil.updateUser(MyApplication.currentUser!!) {
mAuth.signOut()
}
googleSignInClient.signOut()
MyApplication.currentUser = null
navController.navigate(R.id.action_logout)
}
}
true
}
}
private fun getUserData() {
val ref = db.collection("users").document(mAuth.currentUser!!.uid)
ref.get().addOnSuccessListener {
val userInfo = it.toObject(UserModel::class.java)
navViewBinding.user = userInfo
MyApplication.currentUser = userInfo
MyApplication.currentUser!!.active = true
FirestoreUtil.updateUser(MyApplication.currentUser!!) {
}
}.addOnFailureListener {
val intent = Intent(this, MyApplication::class.java)
startActivity(intent)
finish()
}
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(navController, drawerLayout)
}
}
and the XML graphic part related to the HostActivity is the following:
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.instamobile.firebaseStarterKit.ui.activity.host.HostActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="#id/navHostFragment"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/customToolbar"
style="#style/MyToolbarThemeSimple.Base"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.fragment.app.FragmentContainerView
android:id="#+id/navHostFragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/appBar"
app:navGraph="#navigation/main_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/navView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/drawer_header_layout"
app:itemIconTint="#color/colorPrimary"
app:menu="#menu/drawer_menu" />
</androidx.drawerlayout.widget.DrawerLayout>
In the HomeFragment I put only the map and a navigation bar, as you can see in the following code:
class HomeFragment : Fragment() {
private var mapView: MapView? = null
#Nullable
override fun onCreateView(
inflater: LayoutInflater,
#Nullable container: ViewGroup?,
#Nullable savedInstanceState: Bundle?
): View? {
Mapbox.getInstance(
context!!.applicationContext,
"******KEY******"
)
val view: View = inflater.inflate(R.layout.fragment_home, container, false)
mapView = view.findViewById<View>(R.id.mapView) as MapView
mapView!!.onCreate(savedInstanceState)
return view
}
override fun onStart() {
super.onStart()
mapView!!.onStart()
}
override fun onResume() {
super.onResume()
mapView!!.onResume()
}
override fun onPause() {
super.onPause()
mapView!!.onPause()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mapView!!.onSaveInstanceState(outState)
}
override fun onLowMemory() {
super.onLowMemory()
mapView!!.onLowMemory()
}
override fun onDestroyView() {
super.onDestroyView()
mapView!!.onDestroy()
}
}
Finally, the XML code related the HomeFragment graphic part is the following:
<?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=".ui.fragment.home.HomeFragment">
<com.mapbox.mapboxsdk.maps.MapView
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="60dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:layout_gravity="bottom|right"
android:clickable="true"
android:focusable="true"
app:backgroundTint="#4CAF50"
app:srcCompat="#drawable/ic_navigation_white_24dp"
tools:ignore="ContentDescription,MissingConstraints,RtlHardcoded,VectorDrawableCompat" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingActionButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="5dp"
android:layout_marginBottom="100dp"
android:layout_gravity="right|bottom"
android:clickable="true"
android:focusable="true"
app:backgroundTint="#4CAF50"
app:srcCompat="#drawable/ic_taxi"
tools:ignore="ContentDescription,DuplicateIds,MissingConstraints,RtlHardcoded,VectorDrawableCompat" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingActionButton3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_gravity="top|left"
android:clickable="true"
android:focusable="true"
app:backgroundTint="#4CAF50"
app:srcCompat="#drawable/ic_search"
tools:ignore="ContentDescription,DuplicateIds,MissingConstraints,RtlHardcoded,VectorDrawableCompat" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingActionButton4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginBottom="25dp"
android:layout_gravity="bottom|left"
android:clickable="true"
android:focusable="true"
app:backgroundTint="#4CAF50"
app:srcCompat="#drawable/ic_filter"
tools:ignore="ContentDescription,DuplicateIds,MissingConstraints,RtlHardcoded,VectorDrawableCompat" />
</com.mapbox.mapboxsdk.maps.MapView>
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/mapView"
app:menu="#menu/bottom_navigation_menu"
tools:ignore="MissingConstraints" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
The code run, with no errors, but the map does not appear.
Are we doing well?
We cannot find any error in the code. Could you?
Many thanks.
Best
I have the same problem.
I resolved it by the use of the call to getMapAsync.
You have to add this code before return view in HomeFragment.
mapView!!.getMapAsync { mapboxMap ->
mapboxMap.setStyle(Style.MAPBOX_STREETS) {
}

How to handle the back event in nested NavHostFragments?

I did take a look on the official website Nested Graph and searched related issues but have no luck on it.
When the nest graph and dynamic feature module comes up, I tried to combine "dynamic feature module", "Nested NavHostFragments" and "Nested Graph" into a separate module. But when I tried to handle the back button event, I have no idea on it.
I have the NavHostFragments in the "app" module and when the user navigation the account item on the bottom navigation view. It will prompt up a bottomsheetdialog, which contains a nested NavHostFragment and also its navigation graph. And those fragments are inside "account" module.
When I tried to navigation back by pressing back button in the account page, it does not get back the stacks inside the nested NavHostFragment. This setPrimaryNavigationFragment() function seems providing some clue for this issue but i have no luck on it.
That's the current behavior
MainActivity.kt (In "app" module)
class MainActivity : AppCompatActivity() {
private lateinit var toolbar: Toolbar
private lateinit var appBarConfiguration: AppBarConfiguration
private val navController: NavController by lazy {
findNavController(R.id.nav_host_fragment)
}
private val listener =
NavController.OnDestinationChangedListener { controller, destination, arguments ->
model.triggerDestination(destinationId = destination.id)
}
private val model: MainActivityViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
val navView: BottomNavigationView = findViewById(R.id.nav_view)
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_explore
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
model.notificationPageSelect.observe(this, EventObserver {
when (it) {
R.id.navigation_explore -> updateAppBarBg(R.drawable.explore_appbar_bg_gradient)
R.id.navigation_notifications -> updateAppBarBg(R.drawable.notification_appbar_bg_gradient)
}
})
}
private fun updateAppBarBg(appBg: Int) {
toolbar.setBackgroundResource(appBg)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.overflow_menu, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp(appBarConfiguration)
}
override fun onResume() {
super.onResume()
navController.addOnDestinationChangedListener(listener)
}
override fun onPause() {
super.onPause()
navController.removeOnDestinationChangedListener(listener)
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="0dp"
android:layout_height="50dp"
android:background="#drawable/explore_appbar_bg_gradient"
android:theme="#style/ThemeOverlay.MaterialComponents.Dark.ActionBar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/toolbar">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/toolbar"
app:navGraph="#navigation/mobile_navigation" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="?android:attr/windowBackground"
app:labelVisibilityMode="labeled"
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
app:menu="#menu/bottom_nav_menu"
app:layout_anchorGravity="bottom|right|end"
android:layout_gravity="bottom|end"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
AccountListDialogFragment.kt (in "account" module)
class AccountListDialogFragment : BottomSheetDialogFragment() {
private lateinit var viewModel: SettingsViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? = inflater.inflate(R.layout.fragment_account, container, false)
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(SettingsViewModel::class.java)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
setupFullExpand()
}
}
fragment_account.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/account" />
</androidx.constraintlayout.widget.ConstraintLayout>

Custom ToolBar for each Fragment of BottomNavigationBar with Kotlin

Android Studio generated simple template with following MainActivity code:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setupBottomNavigationBar()
}
private fun setupBottomNavigationBar() {
val navView: BottomNavigationView = findViewById(R.id.bottom_nav_view)
val navController = findNavController(R.id.nav_host_fragment)
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
val appBarConfiguration = AppBarConfiguration(setOf(
R.id.navigation_profile, R.id.navigation_chats,
R.id.navigation_conferences, R.id.navigation_settings))
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
And here's activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_nav_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="0dp"
android:layout_marginEnd="0dp"
android:background="#color/colorPrimary"
app:itemIconTint="#color/colorPrimaryDark"
app:itemTextColor="#color/colorPrimaryDark"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:menu="#menu/bottom_nav_menu" />
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#id/bottom_nav_view"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/mobile_navigation" />
</androidx.constraintlayout.widget.ConstraintLayout>
But when I change AppTheme style parent to "Theme.AppCompat.Light.NoActionBar" the app crashes with following error:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.acase/com.example.acase.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.appcompat.app.ActionBar.setTitle(java.lang.CharSequence)' on a null object reference
It's trying to set title of fragment on nonexistent ActionBar.
So the question is how can I setup custom toolbar for each Fragment without showing default toolbar?

Categories

Resources