如何从其他活动/片段中调用内联函数

时间:2020-08-10 23:55:11

标签: android kotlin android-fragments fragmenttransaction

根据How to call this function from other activities?的建议,您好,我遇到了很多问题 所以我跟随并创建了一个Utils kotlin。

Util.kt

package com.example.navigationpractice.Utils

import android.content.Context
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction

inline fun FragmentManager.inTransaction(context: Context,func: FragmentTransaction.() -> FragmentTransaction) {
    beginTransaction().func().commit()
}

我创建了带有片段标签的XML,以便仅在一个活动中进行片段事务。

在从AppCompatActivity扩展的MainActivity中,我做到了这一点,并且运行良好

 supportFragmentManager.inTransaction(this) {
            add(R.id.main_frame,optionsFragment)
        }

现在在片段中对我来说似乎是不可能的...

package com.example.navigationpractice

import android.content.Context
import android.os.Bundle
import android.text.TextUtils.replace
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import com.example.navigationpractice.Utils.inTransaction
import com.example.navigationpractice.databinding.FragmentOptionsBinding
import kotlinx.android.synthetic.main.activity_main.*

class OptionsFragment : Fragment() {

    lateinit var _binding:FragmentOptionsBinding

    val binding get()=_binding



    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding=FragmentOptionsBinding.inflate(layoutInflater)
        val view=binding.root

        val fragmentA=FragmentA()
        val fragmentB=FragmentB()
        val fragmentC=FragmentC()
        val mainActivity=MainActivity()

        binding.buttonA.setOnClickListener {
           // (activity as MainActivity).inTras

//            val transaction=childFragmentManager.beginTransaction()
//            transaction.replace(R.id.main_frame,fragmentA)
//            transaction.addToBackStack(null)
//            transaction.commit()
        }

        binding.buttonB.setOnClickListener {

        }

        binding.buttonC.setOnClickListener {
            val transaction=childFragmentManager.beginTransaction()
            transaction.replace(R.id.main_frame,fragmentC)
            transaction.addToBackStack(null)
            transaction.commit()
        }
        return view
    }

    fun AppCompatActivity.replaceFragment(frameId:Int,fragment:Fragment){
        supportFragmentManager.inTransaction(applicationContext) { replace(frameId, fragment) }

    }


}

注意,我创建了replaceFragment函数...请耐心等待我正在学习kotlin,因此我尝试在按钮A的onClickListener中调用此函数(通过我使用viewBinding的方式)。如您所见,我已经尝试了很多类似的操作,例如(活动称为MainActivity),并且注意到我也尝试过

val transaction=childFragmentManager.beginTransaction()
            transaction.replace(R.id.main_frame,fragmentC)
            transaction.addToBackStack(null)
            transaction.commit()

在按钮C的单击侦听器内部,此代码有错误。

java.lang.IllegalArgumentException: No view found for id 0x7f080091 (com.example.navigationpractice:id/main_frame) for fragment FragmentC{adfd9c} (cafbf662-c429-4b87-9557-47403cb1c30a) id=0x7f080091}
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:315)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
        at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
        at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
        at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
        at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2169)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1992)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
        at androidx.fragment.app.FragmentManager$4.run(FragmentManager.java:413)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6494)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

这就是为什么在进行了一些研究之后,我尝试使用Util方法,但是我不知道在哪里以及如何继续。

片段C ...

package com.example.navigationpractice

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.example.navigationpractice.databinding.FragmentCBinding

class FragmentC : Fragment() {

    private lateinit var _binding:FragmentCBinding
    private val binding get() = _binding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        _binding=FragmentCBinding.inflate(layoutInflater)
        val view=binding.root

        // Inflate the layout for this fragment
        return view
    }
}

片段C XML ...

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".FragmentC">

    <TextView
        android:id="@+id/text_c"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="C"
        android:textColor="@android:color/black"
        android:textSize="40sp"
        android:layout_gravity="center_horizontal|center_vertical"/>

</FrameLayout>

活动主xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

    </androidx.appcompat.widget.Toolbar>

    <fragment
        android:id="@+id/main_frame"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@+id/bottomNavigationView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"
        app:navGraph="@navigation/navigation_graph">

    </fragment>

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNavigationView"
        android:layout_width="match_parent"
        android:layout_height="70dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent">

    </com.google.android.material.bottomnavigation.BottomNavigationView>
</androidx.constraintlayout.widget.ConstraintLayout>

0 个答案:

没有答案