使用fragmenttransaction添加嵌套片段时无法唯一标识布局

问题描述 投票:1回答:1

我正在尝试执行以下操作:

  1. 在活动中,用片段替换容器(TestFragment)
  2. 这个片段的布局包含一个被另一个片段替换的容器(TestSubFragment)
  3. 单击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
1个回答
0
投票

我没有获得新的容器ID就解决了我的问题。

我决定删除fragmenttransaction并在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>
© www.soinside.com 2019 - 2024. All rights reserved.