Программно добавить фрагмент к активности в Kotlin - PullRequest
1 голос
/ 23 января 2020

Я создал фрагмент, который я sh поместил бы в действие.

Пока мой код выглядит так:

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()
    }
}

activity_main. xml

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

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
    }
}

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>

При запуске выдается ошибка:

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}

Ответы [ 4 ]

1 голос
/ 23 января 2020

Исключение говорит о том, что вы пытаетесь добавить фрагмент, который будет связан с несуществующим представлением. На самом деле, я не уверен, откуда взялся 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>

Тогда

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

Так что другой ответ тоже был исправить то, что сказал использовать container и R.id.container, но вам также не хватает setContentView(R.layout.activity_main).

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
0 голосов
/ 23 января 2020

Вам нужно дать вашему фрагменту идентификатор и ссылаться на него в макете активности. Например:


<fragment   android:name=com.example.bluelightlite.models.Team"
            android:id="@+id/Team"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="match_parent" />
0 голосов
/ 23 января 2020

Добавить фрагмент в действие

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
}

Добавить фрагмент во фрагмент

private fun addFragmentToFragment(fragment: Fragment){

 val ft = childFragmentManager.beginTransaction()
    ft.add(R.id.framlayout, fragment, fragment.javaClass.name)
    ft.commitAllowingStateLoss()
}
0 голосов
/ 23 января 2020

замените эту строку идентификатором контейнера, подобным этому

fragmentTransaction.replace(R.id.container, homeFragment).commit()

и добавьте framelayout в вашей основной деятельности xml

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/container"
    />
...