提问人:Иван Петров 提问时间:9/9/2022 更新时间:9/9/2022 访问量:113
无法从 RecyclerView 适配器启动 Fragment
Can't launch Fragment from RecyclerView adapter
问:
NameListHolder 类的代码位于 RecyclerView 适配器中
class NameListHolder(val binding: NameListItemBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(paginationLocalModel: PaginationLocalModel, position: Int, context: NameListFragment){
binding.name.text = paginationLocalModel.name
itemView.setOnClickListener{
val fragment = DescriptionFragment()
val bundle = Bundle()
bundle.putInt("position", position)
fragment.setArguments(bundle)
val activity=context.context as AppCompatActivity
activity.supportFragmentManager
.beginTransaction()
.replace(R.id.rd_fragment, fragment)
.commitNow()
Log.d("OnClick", "произошло нажатие по позиции $position")
}
}
}
在片段内部应该触发,但是当我单击列表项时,会抛出一个:itemView.setOnClickListener
NullPointerException
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sem.receivedata, PID: 5484
java.lang.NullPointerException
at com.sem.receivedata.presentation.DescriptionFragment.<init>(DescriptionFragment.kt:22)
at com.sem.receivedata.presentation.adapters.NameListAdapter$NameListHolder.bind$lambda-0(NameListAdapter.kt:49)
at com.sem.receivedata.presentation.adapters.NameListAdapter$NameListHolder.$r8$lambda$FuXGFWDKhm2ZD3YhtF7Xh98aUvc(Unknown Source:0)
at com.sem.receivedata.presentation.adapters.NameListAdapter$NameListHolder$$ExternalSyntheticLambda0.onClick(Unknown Source:4)
DescriptionFragment.kt:22
指向片段内的字符串val position: Int = bundle!!.getInt("position", 0)
DescriptionFragment
NameListAdapter.kt:49
指向val fragment = DescriptionFragment()
NameListHolder
Unknown Source:0
并始终指向第 0 行和第 4 行,无论那里有什么(在有导入之前)Unknown Source:4
newInstance()
整个数据链:
NameListFragment
:
class NameListFragment : Fragment() {
...
private fun initRecyclerExchangeRate(){
binding?.listNameRV?.layoutManager =
LinearLayoutManager(context)
nameListAdapter = NameListAdapter(this)
binding?.listNameRV?.adapter = nameListAdapter
}
...
}
NameListAdapter
:
class NameListAdapter(var context: NameListFragment
) : RecyclerView.Adapter<NameListAdapter.NameListHolder>() {
...
override fun onBindViewHolder(holder: NameListHolder, position: Int) {
holder.bind(pagination[position], position, context)
}
...
class NameListHolder(val binding: NameListItemBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(paginationLocalModel: PaginationLocalModel, position: Int, context: NameListFragment){
binding.name.text = paginationLocalModel.name
itemView.setOnClickListener{
val fragment = DescriptionFragment()
val bundle = Bundle()
bundle.putInt("position", position)
fragment.setArguments(bundle)
val activity=context.context as AppCompatActivity
activity.supportFragmentManager
.beginTransaction()
.replace(R.id.rd_fragment, fragment)
.commitNow()
Log.d("OnClick", "произошло нажатие по позиции $position")
}
}
}
...
}
DescriptionFragment
:
class DescriptionFragment : Fragment() {
...
val bundle: Bundle? = this.getArguments();
val position: Int = bundle!!.getInt("position", 0)
...
}
Activity 中第一个片段的启动是在标记中完成的:
<?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"
tools:context=".presentation.MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:id="@+id/framelayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="@+id/rd_fragment"
android:name="com.sem.receivedata.presentation.NameListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
答:
您正在此行中创建新片段
val fragment = DescriptionFragment()
因此,它被创建并在开始时尝试解析捆绑包
val bundle: Bundle? = this.getArguments();
val position: Int = bundle!!.getInt("position", 0)
尚未设置,您将在创建后的下一行中执行此操作。但是你一开始就强制从bundle()中读取,就在此时此刻,所以发生了Fragment
!!
null
NullPointerException
你的 aproach 是错误的,你应该阅读一些生命周期方法中的参数,比如 or ,当你被创建的 Shure 时,被设置(例如 arguments set),被添加到布局和运行中(因为它正在调用生命周期方法)onCreate
onCreateView
Fragment
Bundle
评论