Невозможно однозначно идентифицировать макет при добавлении вложенных фрагментов с помощью фрагментации

Я пытаюсь сделать следующее:

  1. В операции замените контейнер фрагментом (TestFragment)
  2. Макет этого фрагмента содержит контейнер, который заменяется другим фрагментом (TestSubFragment)
  3. При нажатии на TestSubFragment действие добавляет новый тестовый фрагмент поверх корневого контейнера

TestActivity.kt

class TestActivity : AppCompatActivity(), TestSubFragment.OnFragmentInteractionListener { override fun onFragmentInteraction(id: Int) { supportFragmentManager.beginTransaction().add(R.id.container, TestFragment.newInstance(id)).addToBackStack(null).commit() } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_test) supportFragmentManager.beginTransaction().replace(R.id.container, TestFragment.newInstance(1)).addToBackStack(null).commit() } } 

TestFragment.kt

 class TestFragment : Fragment() { private var id: Int? = null override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val v = inflater!!.inflate(R.layout.fragment_test, container, false) activity.supportFragmentManager.beginTransaction().replace(R.id.sub_fragment_container, TestSubFragment.newInstance(id!!)).commit() return v } companion object { fun newInstance(id: Int): TestFragment { val fragment = TestFragment() fragment.id = id return fragment } } } 

TestSubFragment.kt

 class TestSubFragment : Fragment() { private var mListener: OnFragmentInteractionListener? = null private var id: Int? = null override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val v = inflater!!.inflate(R.layout.fragment_sub_test, container, false) v.id_text.text = id.toString() v.id_text.setOnClickListener { _ -> mListener?.onFragmentInteraction(v.id_text.text.toString().toInt() + 1) } return v } override fun onAttach(context: Context?) { super.onAttach(context) if (context is OnFragmentInteractionListener) { mListener = context } } interface OnFragmentInteractionListener { fun onFragmentInteraction(id: Int) } companion object { fun newInstance(id: Int): TestSubFragment { val fragment = TestSubFragment() fragment.id = id return fragment } } } 

activity_test.xml

 <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="ckl.happens.TestActivity"> <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1"> </FrameLayout> </android.support.constraint.ConstraintLayout> 

fragment_test.xml

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" tools:context="ckl.happens.TestFragment"> <FrameLayout android:id="@+id/sub_fragment_container" android:layout_width="match_parent" android:layout_height="match_parent"> </FrameLayout> </FrameLayout> 

fragment_sub_test.xml

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" tools:context="ckl.happens.TestFragment"> <TextView android:id="@+id/id_text" android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/hello_blank_fragment" /> </FrameLayout> 

Проблема в том, что строка замены replace в TestFragment.kt находит первый файл R.id.sub_fragment_container из иерархии xml, поэтому он заменяет неправильный контейнер вместо последнего / нового контейнера.

Я попробовал добавить тэг в функцию фрагментации или изменить файл R.id.sub_fragment_container на v.sub_fragment_container.id, но не повезло.

Я не хочу изменять add () для замены () в onFragmentInteraction, потому что фрагмент будет воссоздан, и я хочу сохранить все в фрагменте без изменений, когда пользователь вернется к этому фрагменту.

Я не могу найти подробную статью о вложенных фрагментах для моего дела.

Я работаю с Kotlin, но я также могу понять Java. Спасибо!

Я решил проблему, не получив новый идентификатор контейнера.

Я решил удалить фрагментацию и добавить фрагмент в xml. Затем в фрагменте (родительский фрагмент), который содержит суб-фрагмент, получите под-фрагмент с childFragmentManager.findFragmentById(R.id.fragment) . Наконец, обновите содержимое суб-фрагмента из родительского фрагмента.

 class TestActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_test) val fragment1 = TestFragment.newInstance(1) supportFragmentManager.beginTransaction().replace(R.id.container, fragment1).commit() val fragment2 = TestFragment.newInstance(2) supportFragmentManager.beginTransaction().add(R.id.container, fragment2).addToBackStack(null).commit() val fragment3 = TestFragment.newInstance(3) supportFragmentManager.beginTransaction().add(R.id.container, fragment3).addToBackStack(null).commit() } } class TestFragment : Fragment() { private var id: Int? = null override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { val v = inflater!!.inflate(R.layout.fragment_test, container, false) val subFragment = childFragmentManager.findFragmentById(R.id.fragment) as TestSubFragment subFragment.view?.findViewById<TextView>(R.id.id_text)?.text = id.toString() return v } companion object { fun newInstance(id: Int): TestFragment { val fragment = TestFragment() fragment.id = id return fragment } } } class TestSubFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater!!.inflate(R.layout.fragment_sub_test, container, false) } } 

activity_test.xml

 <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="ckl.happens.TestActivity"> <FrameLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1"> </FrameLayout> </android.support.constraint.ConstraintLayout> 

fragment_test.xml

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" tools:context="ckl.happens.TestFragment"> <fragment android:id="@+id/fragment" android:name="ckl.happens.TestSubFragment" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </FrameLayout> 

fragment_sub_test.xml

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" tools:context="ckl.happens.TestFragment"> <TextView android:id="@+id/id_text" android:layout_width="match_parent" android:layout_height="match_parent" android:text="" /> </FrameLayout> 
Intereting Posts
Drone.getAttribute (AttributeType.Signal) возвращает недействительный сигнал Как запросить Realm в фоновом потоке с помощью RxJava2 Невозможно внедрить один и тот же экземпляр в Сервис и ViewModel Не удается разрешить символ kotlinOptions (в сборке Gradle) Kotlin делегирует собственность ленивым, это нить локальная Android Не удалось создать один или несколько классов Проблемы с доступом к сопутствующему объекту Kotlin в Groovy? Предупреждение Котлина: Условный результат ветви типа … – это импликация любого? android – Модифицировать вызов void с помощью Kotlin Как мы можем использовать автоматическую перезагрузку? Есть ли способ использовать значение по умолчанию для необязательного параметра при передаче null? getChildFragmentManager () не найден в kotlin Попытка мигрировать на канарейку 5 Почему существует NoClassDefFoundError с классом, который существует? filterNotNull в списке Kotlin с общим типом