Navigation Component should initialize fragment once - android

I want to load all fragment once or on first click. I don't want to recreate fragment on clicking bottom menu
MainActivity.kt
#AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var navController:NavController
private lateinit var appBarConfiguration:AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
supportActionBar?.hide()
val navView: BottomNavigationView = binding.navView
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment_activity_main) as NavHostFragment
navController = navHostFragment.navController
appBarConfiguration = AppBarConfiguration(
setOf(
R.id.navigation_home, R.id.navigation_campaigns, R.id.navigation_credits,R.id.navigation_masks,R.id.navigation_messages
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}
override fun onSupportNavigateUp(): Boolean {
return NavigationUI.navigateUp(navController, appBarConfiguration)
}
}

Related

Cannot hide back button on action bar

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()
}
}

NavigationUI.setupActionBarWithNavController and setupActionBarWithNavController

I'm learning android development, Im looking up information about navigation components and fragments but I havent understood what is the diferent between
NavigationUI.setupActionBarWithNavController(this,navHostFragment.navController) and setupActionBarWithNavController(navController,appBarConfig).
bellow you can find two codes, In one Im using NavigationUI but In the other I dont.
First one:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding= ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
NavigationUI.setupActionBarWithNavController(this,navHostFragment.navController)
binding.bnNavBar.setupWithNavController(navHostFragment.navController)
}
override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(R.id.nav_host_fragment)
return navController.navigateUp()
}
}
Second one:
class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener {
private lateinit var mainBinding: ActivityMainBinding
private lateinit var appBarConfiguration: AppBarConfiguration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mainBinding = ActivityMainBinding.inflate(layoutInflater)
setContentView(mainBinding.root)
val toolBar = mainBinding.activityMainContent.mainToolbar
//Setting up the tool bar as the app bar for the activity
setSupportActionBar(toolBar)
val host: NavHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment_container) as NavHostFragment
val navController = host.navController
//appBarConfiguration = AppBarConfiguration(navController.graph)
appBarConfiguration = AppBarConfiguration(
setOf(R.id.continentFragment),
mainBinding.drawerLayout
)
//First
setUpActionBar(navController,appBarConfiguration)
//Second
setUpNavigationView(navController)
}
private fun setUpActionBar(navController: NavController, appBarConfig : AppBarConfiguration) {
setupActionBarWithNavController(navController,appBarConfig)
}
private fun setUpNavigationView(controller: NavController) {
mainBinding.navView.setupWithNavController(controller)
}
override fun onNavigationItemSelected(item: MenuItem): Boolean {
mainBinding.drawerLayout.closeDrawer(GravityCompat.START)
return true
}
override fun onSupportNavigateUp(): Boolean {
val navController = findNavController(R.id.nav_host_fragment_container)
return navController.navigateUp(appBarConfiguration)|| super.onSupportNavigateUp()
}
override fun onBackPressed() {
if (mainBinding.drawerLayout.isDrawerOpen(GravityCompat.START)) {
mainBinding.drawerLayout.closeDrawer(GravityCompat.START)
} else {
super.onBackPressed()
}
}
}
Please, I'd be very thankful if someone can explain me the diference.
Ive read a lot about navigation but I havent found anything useful

How to return to previous activity when using Navigation Component and Up navigation (back button on toolbar)

First Activity
class MainActivity : AppCompatActivity() {
private lateinit var navHostFragment: NavHostFragment
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var navController: NavController
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.lifecycleOwner = this
navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
navController = navHostFragment.navController
appBarConfiguration = AppBarConfiguration(setOf(R.id.fragment))
setupActionBarWithNavController(navController, appBarConfiguration)
navController.navigate(R.id.secondActivity, SecondActivityArgs(someId = "test").toBundle())
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
Second Activity
class SecondActivity : AppCompatActivity() {
private lateinit var navHostFragment: NavHostFragment
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var navController: NavController
private lateinit var binding: ActivitySecondBinding
private val args: SecondActivityArgs by navArgs()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_second)
binding.lifecycleOwner = this
val someId = args.someId
navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
navController = navHostFragment.navController
appBarConfiguration = AppBarConfiguration(emptySet())
setupActionBarWithNavController(navController, appBarConfiguration)
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
}
Manifest
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SecondActivity"
android:parentActivityName=".MainActivity"
android:exported="true" />
When I'm on the second activity and I press the up button on the toolbar it recreates SecondActivity instead of returning to MainActivity
If I use back button instead of up button then it works fine
What could be a problem and how to fix it?
I press up button and it just destroys the second activity and starts it again
You can try something like
public boolean onOptionsItemSelected(MenuItem item)
{
if (item.getItemId() == android.R.id.home)
{
NavUtils.navigateUpFromSameTask(this);
return true;
}
...
}

Trying to replace one Fragment with another in android studio (Kotlin)

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()
})

Why Nav Controller can't be declared as class variable?

I'm new to android and working through some tutorials. Currently working on implementing the Navigation controller and overriding the up button functionality. Part of doing this is to link the action bar with the Nav controller and overriding onSupportNavigateUp(). In doing this I noticed that we have to fetch the Nav Controller by id twice so I decided to create a class variable that does this and re-use the variable. The problem is the App crashes on startup when I do this. My guess is this is because I'm trying to get the Nav Controller before inflating the views?
So my question is why does this work:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
#Suppress("UNUSED_VARIABLE")
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
val navController = this.findNavController(R.id.myNavHostFragment)
NavigationUI.setupActionBarWithNavController(this, navController)
}
override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(R.id.myNavHostFragment)
return navController.navigateUp()
}
}
But this doesn't work:
class MainActivity : AppCompatActivity() {
private val navController = this.findNavController(R.id.myNavHostFragment)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
#Suppress("UNUSED_VARIABLE")
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
NavigationUI.setupActionBarWithNavController(this, navController)
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp()
}
}
You are right, you are assigning the navController before the view is inflated and passed the null to setupActionBarWithNavController
You can do it like this,
class MainActivity : AppCompatActivity() {
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
#Suppress("UNUSED_VARIABLE")
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
NavigationUI.setupActionBarWithNavController(this, navController)
navController = this.findNavController(R.id.myNavHostFragment)
}
override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp()
}
}

Categories

Resources