Я пытаюсь сделать следующее:
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>