Open fragment from another one in kotlin

14,463

Solution 1

It is simple as it is in activity just do it like this.

 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    childFragmentManager.beginTransaction().replace(R.id.action_container,ChildFragment.getInstance()).commit()
}

Solution 2

Use below function inorder to add or replace any fragment

fun addFragment(
fm: FragmentManager,
fragment: Fragment,
container: Int,
replace: Boolean,
addToBackStack: Boolean,
addAnimation: Boolean
) {
val fragmentTransaction = fm.beginTransaction()
if (addAnimation)
    fragmentTransaction.setCustomAnimations(
        R.animator.slide_in_rght,
        R.animator.slide_out_left,
        R.animator.slide_in_left,
        R.animator.slide_out_rght
    )
if (replace)
    fragmentTransaction.replace(container, fragment, fragment.javaClass.name)
else
    fragmentTransaction.add(container, fragment, fragment.javaClass.name)
if (addToBackStack)
    fragmentTransaction.addToBackStack(fragment.javaClass.name)
 fragmentTransaction.commit()
}

In your fragment class where you want to open another fragment , you can call the above function :

fragmentManager?.let {
                        addFragment(
                            it, ABCFragment(), android.R.id.content, false,  true,
                            true
                        )
                    }

or

addFragment(
                        activity?.supportFragmentManager
                        , SignupFinalStepFragment.newInstance(
                            phoneNumber = phoneNumber?:"",
                            emailAddress = emailAddress ?: ""
                        ), android.R.id.content, false, addToBackStack = true,
                        addAnimation = true
                    )

Both the method calls are same , the only difference is activity?.supportFragmentManager which should be non null .

Solution 3

If you are using a Fragment, you can get the context of the activity and retrieve the fragment manager from it. So, inside your fragment class do this

FragmentManager fm = ((Activity) getContext).getSupportFragmentManager();

Not that you have your fragment manager, you only need the id of the container that you want to add/replace your other fragment and you are good to go.

fm.beginTransaction().add(R.layout.container_id, OtherFragmentObject()).commit();

Solution 4

In your CurrentFragment, override the onActivityCreated like so:

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    yourOwnButton.setOnClickListener{

        requireActivity().supportFragmentManager.beginTransaction()
            .replace(R.id.your_fragment_container, AnotherFragment.newInstance())
            .commit()
    }
}

and inside your AnotherFragment you should have a companion object like so:

companion object {
    fun newInstance() = StudentFragment()
}
Share:
14,463
Lucile S
Author by

Lucile S

Updated on June 05, 2022

Comments

  • Lucile S
    Lucile S almost 2 years

    I'm totally desesperate. I try to open/replace fragment from one to another and only docs I can find is from an Activity or only in Java (with the getFragmentManager() method, seems to not exist in Kotlin).

    supportFragmentManager is only available inside an Activity, and I'm using a fragment and adapter.

    Could you please help me?

    I think it's unless to show my code because it's just give nothing, only errors

    None of the answers worked for me. I tried something else and create an interface :

    interface AdapterCallbackAlbum {
    fun onClickItem(album: Album)}
    

    And implement this in my first fragment

    class ListAlbumsFragment : Fragment(), AdapterCallbackAlbum {
      override fun onClickItem(album: Album) {
      val fragment = ListTracksFragment.newInstance()
      val transaction = childFragmentManager.beginTransaction()
      transaction.replace(R.id.album_fragment, fragment)
      transaction.commit()
    }
    

    And finally the adapter:

        class AlbumAdapter(val context: Context, private val 
        adapterCallbackAlbum: AdapterCallbackAlbum): Adapter<ViewHolder>() {
        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, 
        position: Int) {
            val album = albumList[position]
            holder.itemView.setOnClickListener { 
              adapterCallbackAlbum.onClickItem(album)
           }}
    

    But the only result I get is the second fragment put on the first one even if I call a :

    transaction.remove(ListAlbumFragment.newInstance())
    

    A friend of mine finally solved my problem (maybe it could help someone).

     override fun onClickItem(album: Album) {
        val fragment = ListTracksFragment.newInstance()
        val transaction = fragmentManager.beginTransaction()
        transaction.replace(R.id.content, fragment)
        transaction.addToBackStack(null)
        transaction.commit()
    }
    

    The trouble was we start from MainActivity, which load a fragment, inside this fragment, we have to load another one on a click event. So the fragment to replace is not the current fragment, but the content of main_activity.xml.

    Thank's to all for your quick answers

  • Jorgesys
    Jorgesys over 4 years
    This is not Kotlin!
  • Jorgesys
    Jorgesys over 4 years
    How could we get childFragmentManager ?
  • mightyWOZ
    mightyWOZ over 4 years
    Thanks for your answer, please try to explain how and why your solution works.