How to replace fragment inside another fragment in Kotlin? - android

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

Related

Navigating back to the previous Fragment not working

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

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

error: java.lang.NullPointerException: toolbar must not be null

I am using a navigation drawer .My app was working fine before that but after the code of navigation from drawer to fragment , it is showing this error! Should i change something in style?
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
val navController = NavHostFragment.findNavController(nav_host_fragment)
val appBarConfiguration = AppBarConfiguration(navController.graph)
toolbar.setupWithNavController(navController, appBarConfiguration)
}
this is my fragment code i.e. when i will click on the drawer item i will be navigated to this fragment.

Replace bottom navigation view with fragment

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

Navigate to specific fragment on BottomNavigationView

I've searched my problem but I could not find anything. let me describe my problem.
I have 3 buttons on BottomNavigationView (Home, User, History). then from other activity, I have a button which I want is going to User page (with BottomnavigationView of course.
I will show you my code. it still defaults all. I just do not know how to navigate to the User page.
MainActivity.kt
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)
// 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_home, R.id.navigation_user, R.id.navigation_notifications
)
)
setupActionBarWithNavController(navController, appBarConfiguration)
navView.setupWithNavController(navController)
}}
and here is my code (from other fragment)
otherFragment.kt
buttonRincian.setOnClickListener {
// i dont know command to go to MainActivity with User page as default selected menu
}
thank you so much, i hoe someone can help me.
Make an interface which your activity will implement.
All the fragments should call the method of the interface wherever you want to change the fragment.
something like
interface TabChangeListener {
fun onTabChange(tabName : String)
}
Code in Activity
class Activity : AppCompatActivity(), TabChangeListener {
override fun onTabChange(tabName : String) {
//code to show different tabs
}
}
Code in Fragments
class Frag1 : Fragment {
var listener : TabChangeListener
//somewhere in the code
listener.onTabChange("userTab")
}
Don't forget to take the reference of TabChangeListener in Fragments from the activity otherwise the callbacks won't work.

Categories

Resources