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

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

  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>