【发布时间】:2017-12-28 00:20:46
【问题描述】:
我正在尝试执行以下操作:
- 在活动中,替换容器为片段 (TestFragment)
- 此片段的布局包含一个容器,该容器被另一个片段 (TestSubFragment)替换
- 单击 TestSubFragment 会使活动在根容器上添加一个新的 TestFragment
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>
问题是 TestFragment.kt 中的替换片段行正在从 xml 层次结构中找到第一个 R.id.sub_fragment_container,因此它正在替换不正确的容器而不是最后一个/新容器。
我尝试在 fragmenttransaction 中添加标签或将 R.id.sub_fragment_container 更改为 v.sub_fragment_container.id 但没有运气。
我不想在 onFragmentInteraction 中将 add() 更改为 replace(),因为片段将被重新创建,并且我希望在用户返回该片段时保持片段中的所有内容不变。
我找不到关于我的案例嵌套片段的详细文章。
我正在使用 Kotlin,但我也能理解 Java。谢谢!
【问题讨论】:
标签: java android android-fragments kotlin