I have MainActivity with BottomNavigationView like so:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navView: BottomNavigationView = findViewById(R.id.nav_view)
val navController = findNavController(R.id.nav_host_fragment)
navView.setupWithNavController(navController)
}
}
Also, I have a setting button on top of the navigation view. On this button click, I wish the setting fragment appear on top of the navigation fragment and hide it and display the setting in full screen.
Something like so:
val settingsFragment = SettingFragment.newInstance()
val fragmentTransaction = supportFragmentManager.beginTransaction()
fragmentTransaction.addToBackStack(null)
fragmentTransaction.replace(/*what to user here*/, settings)
fragmentTransaction.commit()
Here is the solution:
val navHostFragment
= supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
navHostFragment.childFragmentManager
.beginTransaction()
.replace(navHostFragment.id, SettingsFragment())
.addToBackStack(null)
.commit()
Related
My application have two top level fragment A and B controlled by a bottom navigation bar and fragment C can be navigated only from fragment B. I don't want the action bar on fragment C shows back button while it cannot be hidden by setDisplayShowHomeEnabled() or setDisplayHomeAsUpEnabled()
How can I hide the back button?
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val navController = findNavController(R.id.navHostFragment)
val appBarConfiguration = AppBarConfiguration(
setOf(R.id.aFragment, R.id.bFragment)
)
setupActionBarWithNavController(navController, appBarConfiguration)
binding.navView.setupWithNavController(navController)
}
}
Try to set home fragment destination
var navHostFragment = supportFragmentManager
.findFragmentById(R.id.container) as NavHostFragment
var mNavController = navHostFragment.findNavController()
override fun onSupportNavigateUp(): Boolean {
return when (mNavController.currentDestination?.id) {
R.id.homeFrg -> {
true
}
else -> mNavController.navigateUp()
}
}
I'm developing a simple app, with several static screens, just. I get working passing from first fragment, but can't go back to any screen ever.
I saw some videos, like shorturl.at/jFPRY, but in any cases makes work. In my MainActivity I have the OnCreate method, where I save the instance, set the layout, and add a Listener to options on my menu itens.
In the first click, when I open the app, it goes to correct destiny. However, when I click another item it does nothing, stucked. I need to set the Fragments bidirectional, in other words, the user can view any fragment in any moment from any fragment.
My OnCreate method:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
setSupportActionBar(binding.appBarMain.toolbar)
val drawerLayout: DrawerLayout = binding.drawerLayout
val navView: NavigationView = binding.navView
navView.setNavigationItemSelectedListener {
when (it.itemId) {
R.id.nav_conheca_a_UFTM -> {
supportFragmentManager.beginTransaction()
.replace(R.id.drawer_layout, ConhecaUftmFragment())
.commit()
// Remove the other operations
supportFragmentManager.beginTransaction().addToBackStack(null);
}
R.id.nav_calendario_academico -> {
supportFragmentManager.beginTransaction()
.replace(R.id.drawer_layout, GalleryFragment())
.commit()
// Remove the other operations
supportFragmentManager.beginTransaction().addToBackStack(null);
}
R.id.nav_mural_de_informacoes -> {
supportFragmentManager.beginTransaction()
.replace(R.id.drawer_layout, CalendarioFragment())
.commit()
// Remove the other operations
supportFragmentManager.beginTransaction().addToBackStack(null);
}
}
it.isChecked = true
drawerLayout.closeDrawers()
true
}
supportActionBar?.apply {
setDisplayHomeAsUpEnabled(true)
}
navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main)
val appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
NavigationUI.setupWithNavController(binding.appBarMain.toolbar, navController, appBarConfiguration)
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
}
I have also the method onSupportNavigateUp:
override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(id.nav_host_fragment_content_main)
return navController.navigateUp()
}
And here is an example of Fragment that I have:
class GalleryFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_calendario_academico, container, false)
/* view.setOnClickListener(){ Navigation.findNavController(view).
navigate(R.id.conhecauftmToaprimorando)
}*/
return view
}
override fun onDestroyView() {
super.onDestroyView()
}
}
I will pass my GitHub link, if anyone can help to fix this issue.
First approach would be to not use FragmentTransactions when you using NavComponent.
If you have the MenuOptions on the MainActivity layout (which I don't recommend, it should go on every fragment, so the MenuOptions are correlated to the current fragment) you can define your navigations in the nav_graph.xml and use them in the MainActivity through NavigationDirections object.
Please visit https://developer.android.com/guide/navigation/navigation-getting-started for more info.
If you want to come back from GalleryFragment to where you have defined the destination of the Popback behaviour, you should call: findNavController.popBackStack()
I am trying to create an OnClickListener that changes the fragment inside of a NavController and I keep getting nothing to happen on button press. Here is my code so far:
MainActivity:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val navView: BottomNavigationView = binding.navView
val navController = findNavController(R.id.nav_host_fragment_activity_main)
val appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_check_in, R.id.navigation_dashboard, R.id.navigation_new_emp
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
CheckInFragment:
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.newEmpBtn.setOnClickListener(View.OnClickListener {
requireActivity().supportFragmentManager.commit {
replace(R.id.nav_host_fragment_activity_main, NewEmpFragment().newInstance())
setReorderingAllowed(true)
addToBackStack(null)
}
})
}
Currently, this code is not giving an error it just seems to not be working and I've been searching through forums for the last couple of hours. Any ideas would be great!
I think you are missing beginTransaction(). You can try this.
binding.newEmpBtn.setOnClickListener(View.OnClickListener {
val fragmentManager = parentFragmentManager
val fragmentTransaction: FragmentTransaction = fragmentManager.beginTransaction()
fragmentTransaction.replace(
R.id.nav_host_fragment_activity_main,
NewEmpFragment()
)
fragmentTransaction.addToBackStack(null)
fragmentTransaction.commit()
})
For navigation, I use the Navigation The component I connected to it using the Navigation Extension BottomNavigationView. I tried to switch from one graph to another, but he always showed me an error that he could not find a path where to go. If the way to go from one graph to another
the code where the Navigation Component and bottomNavView are connected
class MainActivity : AppCompatActivity(R.layout.activity_main) {
private lateinit var appBarConfiguration: AppBarConfiguration
private var currentNavController: LiveData<NavController>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
if (savedInstanceState == null) {
initNavigationComponent()
}
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
initNavigationComponent()
}
override fun onSupportNavigateUp(): Boolean {
return currentNavController?.value?.navigateUp(appBarConfiguration) ?: false
|| super.onSupportNavigateUp()
}
private fun initNavigationComponent() {
appBarConfiguration =
AppBarConfiguration(setOf(R.id.auth_fragment, R.id.main_screen_fragment))
setSupportActionBar(toolbar)
val navGraphIds =
listOf(R.navigation.nav_main, R.navigation.nav_catalog, R.navigation.nav_profile)
// Setup the bottom navigation view with a list of navigation graphs
val controller = bottom_nav.setupWithNavController(
navGraphIds = navGraphIds,
fragmentManager = supportFragmentManager,
containerId = R.id.main_nav_fragment,
intent = intent
)
controller.observe(this, { navController ->
setupActionBarWithNavController(navController,appBarConfiguration)
collapsingToolbarLayout.setupWithNavController(
toolbar,
navController,
appBarConfiguration
)
navController.addOnDestinationChangedListener {...} )
currentNavController = controller
}
}
Tried connecting with <include app:graph = "#navigation/myGraph" /> but that doesn't work either
for multi backstack navigation between BottomNavigationView tabs use this sample of google:
Multiple BackStack Navigation
So, I use the latest version of androidstudio and kotlin.
I created a bottom navigation activity project, and I use the activity with the drefault generated code.
I would like to open/replace a fragment from another fragment by button.
But the previous fragment doesn't disappear, when the new fragment is appear, so both are visible.
I read a lot, but I don't know the solution, please help me with some advice.
This is my MainActivity
override fun onCreate(savedInstanceState: Bundle ? ) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val navView: BottomNavigationView = findViewById(R.id.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_advertisements, R.id.navigation_own_advertisements, R.id.navigation_chat, R.id.navigation_party, R.id.navigation_settings))
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
And this is my fragment
override fun onViewCreated(view: View, savedInstanceState: Bundle ? ) {
super.onViewCreated(view, savedInstanceState)
button.setOnClickListener {
activity!!.supportFragmentManager
.beginTransaction()
.replace(R.id.nav_host_fragment, ChatFragment())
.commit()
}
}