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