Как изменить фрагмент котлина

Я начинаю в Котлинге и не знаю, как переключаться между фрагментами, я пробовал этот код:

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

R.layout.fragment_information.toInt()

Но у меня ошибка с этим параметром, потому что он не находит идентификатор фрагмента.

Возможный дубликат Фрагмент в котлине

Moustafa EL-Saghier 13.09.2018 18:47
5
1
26 357
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Когда вы добавляете фрагмент, вам нужно добавить его к идентификатору, который существует в макете вашей деятельности, а не ко всему макету:

supportFragmentManager.beginTransaction().add(R.id.some_id_in_your_activity_layout, ComplainFragment()).commit()
Ответ принят как подходящий

Я обычно использую замену для переключения между фрагментами. Также измените R.layout.fragment_information только на R.id.fragment_layout_id, поэтому нет необходимости toInt ()

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

Вот мое предложение.

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

На случай, если кому-то еще нужен быстрый подход к этому. Я создал функцию, которую можно легко вызвать, когда вам нужно изменить фрагмент.

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

R.id.frame в этом случае - это идентификатор моего Framelayout в действии, которое будет содержать мой фрагмент. Все, что вам нужно сделать, это вызвать функцию.

replaceFragment(HomeFragment())

Другие ответы будут работать, но мы все же можем многое улучшить, используя функции расширения в Kotlin.

Добавьте функцию расширения в класс FragmentManager, как показано ниже,

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

затем создайте функцию расширения для класса AppCompatActivity,

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

Теперь, чтобы добавлять и удалять фрагменты из любой активности, вам просто нужно вызвать вот так:

addFragment(R.id.fragment_container, fragment)

replaceFragment(R.id.fragment_container, fragment)

пожалуйста, обратитесь к приведенной ниже ссылке для получения дополнительной информации,

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

Это лучший ответ, но мне любопытно, как я могу добавить эту функцию в класс fragmentManager, если он доступен только для чтения. у меня есть это удовольствие в mainActivity, но как я могу назвать это в котлине?

Felipe Franco 11.08.2020 00:36

Это пример перехода к фрагменту или действию, щелкнув кнопку внутри другого фрагмента:

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

Библиотека реактивного ранца фрагмент-ktx содержит удобные функции расширения, которые упрощают многие вещи, включая транзакции:

// MyActivity.kt

class MyActivity : AppCompatActivity() {
  ...

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

R.id.fragment_container - это идентификатор контейнера фрагмента в родительском макете. Есть FragmentContainerView, который является контейнером рекомендуемые, например:

<!-- 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>

Но если ваша цель - реализовать навигацию внутри приложения, лучше и намного проще использовать Компонент навигации вместо ручного переключения фрагментов.

Другие вопросы по теме