在 Kotlin 中以编程方式将 Fragment 添加到 Activity

Mar*_*man 5 xml android android-fragments kotlin

我已经构建了一个片段,我希望将其放置在活动中。

到目前为止,我的代码如下所示:

MainActivity.kt

class MainActivity: AppCompatActivity() {

    @Inject
    lateinit var teamInfoModule: TeamInfoModule;

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        DaggerServiceModuleComponent.create().inject(this)

        val bundle = Bundle()
        val teamArrayList: ArrayList<Team> = this.teamInfoModule.getAllTeamData()
        val homeFragment = HomeFragment()

        bundle.putParcelableArrayList("teamData", teamArrayList)
        homeFragment.arguments = bundle

        val fragmentManager: FragmentManager = supportFragmentManager
        val fragmentTransaction: FragmentTransaction = fragmentManager.beginTransaction()
        fragmentTransaction.replace(R.id.home_fragment, homeFragment).commit()
    }
}
Run Code Online (Sandbox Code Playgroud)

活动主文件

<layout 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">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:id="@+id/activity_main">
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)

HomeFragment.kt

class HomeFragment @Inject constructor(): Fragment() {

    lateinit var team: Team

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        super.onCreateView(inflater, container, savedInstanceState)

        DaggerServiceModuleComponent.create().inject(this)

        val binding: ViewDataBinding = DataBindingUtil.inflate<ViewDataBinding>(inflater, R.layout.layout_home, container, false)
        print(arguments.toString())
        val allTeams: ArrayList<Team> = arguments?.get("teamData") as ArrayList<Team>

        this.team = allTeams[0]

        binding.setVariable(BR.team, team)

        return binding.root
    }
}
Run Code Online (Sandbox Code Playgroud)

layout_home.xml(绑定到 HomeFragment)

<?xml version="1.0" encoding="utf-8"?>

<layout 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">

    <data>
        <variable
            name="team"
            type="com.example.bluelightlite.models.Team" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".fragments.HomeFragment">

        <androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="1dp"
            android:layout_marginTop="79dp"
            android:layout_marginEnd="1dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <TextView
                android:id="@+id/info_text"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:text="@{team.name}"/>
        </androidx.cardview.widget.CardView>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Run Code Online (Sandbox Code Playgroud)

当它运行时,我收到错误:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.bluelightlite, PID: 10421
    java.lang.IllegalArgumentException: No view found for id 0x7f07003a (com.example.bluelightlite:id/activity_main) for fragment HomeFragment{4b02ab3 (55c458bd-2931-48c6-8087-5e82641313c1) id=0x7f07003a}
Run Code Online (Sandbox Code Playgroud)

小智 8

将片段添加到 Activity

private fun addFragmentToActivity(fragment: Fragment?){

    if (fragment == null) return
    val fm = supportFragmentManager
    val tr = fm.beginTransaction()
    tr.add(R.id.framlayout, fragment)
    tr.commitAllowingStateLoss()
    curFragment = fragment
}
Run Code Online (Sandbox Code Playgroud)

在片段中添加片段

private fun addFragmentToFragment(fragment: Fragment){

 val ft = childFragmentManager.beginTransaction()
    ft.add(R.id.framlayout, fragment, fragment.javaClass.name)
    ft.commitAllowingStateLoss()
}
Run Code Online (Sandbox Code Playgroud)


Epi*_*rce 6

异常表示您正在尝试添加与不存在的视图关联的片段。事实上,我不确定从哪里来R.id.home_fragment

解决方案是这样的:

<FrameLayout
    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=".MainActivity"
    android:id="@+id/root_container">
</FrameLayout>
Run Code Online (Sandbox Code Playgroud)

然后

if(savedInstanceState == null) { // initial transaction should be wrapped like this
    supportFragmentManager.beginTransaction()
           .replace(R.id.root_container, homeFragment)
           .commitAllowingStateLoss()
}
Run Code Online (Sandbox Code Playgroud)

所以另一个答案也是正确的,即使用containerand R.id.container,但你也失踪了setContentView(R.layout.activity_main)

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
Run Code Online (Sandbox Code Playgroud)