java - 使用fragmenttransaction添加嵌套fragment时无法唯一标识布局

标签 java android android-fragments kotlin

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

  1. 在 Activity 中,用 fragment (TestFragment) 替换容器
  2. 此 fragment 的布局包含一个容器,该容器被另一个 fragment (TestSubFragment)替换
  3. 单击 TestSubFragment 会使 Activity 在根容器上添加一个新的 TestFragment

测试 Activity .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()
}
}

测试 fragment .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 中的替换 fragment 行正在从 xml 层次结构中查找第一个 R.id.sub_fragment_container,因此它替换了不正确的容器,而不是最后一个/新容器。

我尝试在fragmenttransaction中添加标签或将R.id.sub_fragment_container更改为v.sub_fragment_container.id,但没有成功。

我不想在onFragmentInteraction中将add()更改为replace(),因为 fragment 将被重新创建,并且当用户返回该 fragment 时我希望保持 fragment 中的所有内容不变。

我找不到有关我的案例的嵌套 fragment 的详细文章。

我正在使用 Kotlin,但我也能理解 Java。谢谢!

最佳答案

我在没有获取新容器 ID 的情况下解决了问题。

我决定删除fragmenttransaction并在xml中添加 fragment 。然后在包含子 fragment 的 fragment (父 fragment )中,使用childFragmentManager.findFragmentById(R.id.fragment)获取子 fragment 。最后从父fragment更新子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>

关于java - 使用fragmenttransaction添加嵌套fragment时无法唯一标识布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47981632/

相关文章:

java - 有一个扩展抽象类的空子类可以吗?

java - 尝试在同一 Activity 中从纯文本(框)打印用户输入

Android 应用程序在开始使用 SQLite 数据库时启动后立即崩溃

java - 奇怪的 glVertexAttrib 行为?

java - 匹配两个字符串中长度为 2(同一索引)的子序列

android - 无法在Eclipse中使用NDK生成APK文件

android - ScrollView 没有滚动到内部 LinearLayout 底部边距的末尾

java - findfragmentbyid 在 vi​​ewpager 下托管 3 个 fragment 的 mainActivity 中返回 null

android - 如何从抽屉导航启动 Activity ?

android - 可折叠 View 不适用于 viewpager