How to change Fragment Kotlin

Viewed 37940

I'm starting in Kotling and I don't know how to change between fragments, I have tried this code:

val manager = supportFragmentManager
    val transaction = manager.beginTransaction()
    transaction.add(R.layout.fragment_information.toInt(), ComplainFragment())
    transaction.commit()

R.layout.fragment_information.toInt()

But i have an error with this parameter because it doesn't find the fragment Id.

8 Answers

I usually use replace to change between fragments. Also change R.layout.fragment_information to R.id.fragment_layout_id only, so no need toInt()

transaction.replace(R.id.fragment_layout_id, fragment)

Here is my suggestion.

    var fragment: Fragment? = null

            when (itemId) {
                        R.id.fragment_information -> {
                            fragment = ComplainFragment()
                        }
            }

            if (fragment != null) {
                    val transaction = supportFragmentManager.beginTransaction()
                    transaction.replace(R.id.fragment_layout_id, fragment)
                    transaction.commit()
            }

The other answers will work but still we can improve a lot by using extension functions in Kotlin.

Add an extension function to the FragmentManager class like below,

inline fun FragmentManager.doTransaction(func: FragmentTransaction.() -> 
FragmentTransaction) {
    beginTransaction().func().commit()
}

then create an extension function to the AppCompatActivity class,

fun AppCompatActivity.addFragment(frameId: Int, fragment: Fragment){
    supportFragmentManager.doTransaction { add(frameId, fragment) }
}


fun AppCompatActivity.replaceFragment(frameId: Int, fragment: Fragment) {
    supportFragmentManager.doTransaction{replace(frameId, fragment)}
}

fun AppCompatActivity.removeFragment(fragment: Fragment) {
    supportFragmentManager.doTransaction{remove(fragment)}
}

Now, to add and remove fragments from any activity, you just need to call like this,

addFragment(R.id.fragment_container, fragment)

replaceFragment(R.id.fragment_container, fragment)

please refer the below link for more info,

https://medium.com/thoughts-overflow/how-to-add-a-fragment-in-kotlin-way-73203c5a450b

This is an example for you to go to a fragment or activity by clicking a button inside another fragment:

class Fragment_One: Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_one, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        btn_goToActivity2.setOnClickListener {
            val intent = Intent(context, SecondActivity::class.java)
            startActivity(intent)
        }

        btn_goToFragment2.setOnClickListener {
            var fr = getFragmentManager()?.beginTransaction()
            fr?.replace(R.id.fragment, Fragment_Two())
            fr?.commit()
        }
    }
}

When you add a fragment, you need to add it to an ID that exists in your Activity's layout, not an entire layout:

supportFragmentManager.beginTransaction().add(R.id.some_id_in_your_activity_layout, ComplainFragment()).commit()

In case anyone still needs a quick approach to this. I created a function than can be easily called whenever you need to change a fragment.

 private fun replaceFragment(fragment: Fragment) {
    val transaction = supportFragmentManager.beginTransaction()
    transaction.replace(R.id.frame, fragment)
    transaction.commit()
}

R.id.frame in this case is the id of my Framelayout in the activity that will hold my fragment. All you have to do now is call the function.

replaceFragment(HomeFragment())
private fun transitionFragment(fragment: Fragment) {
    val transition = requireActivity().supportFragmentManager.beginTransaction()
    transition.replace(R.id.fragment_container_create_void_parent, fragment)
              .addToBackStack(null).commit()
}

fragment-ktx jetpack library contains convenient extension functions which simplify many things, including transactions:

// MyActivity.kt

class MyActivity : AppCompatActivity() {
  ...

  fun showMyFragment() {
    val fragment = MyFragment()
    supportFragmentManager.commit {
      replace(R.id.fragment_container, fragment)
    }
  }
}

R.id.fragment_container it's an id of a fragment container in the parent layout. There's FragmentContainerView which is the recommended container, for example:

<!-- my_activity_layout.xml -->

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout ...>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container"
        ... />

    ...

</androidx.constraintlayout.widget.ConstraintLayout>

But if your purpose is to implement in-app navigation, it's better and much easier to use Navigation component instead of manually switching fragments.

this is my solution for Change current fragment to orther in kotlin:

val supportFragment = SupportFragment()
requireActivity().supportFragmentManager.beginTransaction()
                 .add(this.id, supportFragment)
                 .addToBackStack("ok")
                 .commit()
Related