如何在Fragment类中访问RecyclerView内的TextView控件ID?
问题:Fragment中无法访问RecyclerView子项的TextView并触发空指针异常
问题场景
我在Fragment布局里使用了RecyclerView,对应的子项布局XML包含tvTitle等TextView控件。尝试在Fragment类中直接访问该TextView以执行Fragment事务,编写了如下代码:
var titleTextView = view.findViewById<TextView>(R.id.tvTitle) val subjectFragment = SubjectFragment() println(titleTextView.text)
运行后触发空指针异常,报错日志如下:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.samachar, PID: 7038 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.CharSequence android.widget.TextView.getText()' on a null object reference at com.example.samachar.NewsFragment.onViewCreated(NewsFragment.kt:86) at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2987) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:546) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282) at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189) at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100) at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002) at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3138) at androidx.fragment.app.FragmentManager.dispatchActivityCreated(FragmentManager.java:3072) at androidx.fragment.app.FragmentController.dispatchActivityCreated(FragmentController.java:251) at androidx.fragment.app.FragmentActivity.onStart(FragmentActivity.java:502) at androidx.appcompat.app.AppCompatActivity.onStart(AppCompatActivity.java:248) at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1435) at android.app.Activity.performStart(Activity.java:8024) at android.app.ActivityThread.handleStartActivity(ActivityThread.java:3475) at android.app.servertransaction.TransactionExecutor.performLifecycleSequence(TransactionExecutor.java:221) at android.app.servertransaction.TransactionExecutor.cycleToPath(TransactionExecutor.java:201) at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:173) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) I/Process: Sending signal. PID: 7038 SIG: 9
我的目标是通过FragmentManager执行事务切换布局:
// var fragment = parentFragmentManager?.beginTransaction() // fragment?.replace(R.id.newsFrameLayout, subjectFragment) // fragment?.commit()
但始终无法在Fragment类中直接访问到RecyclerView子项里的TextView控件。
RecyclerView子项的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:id="@+id/newsItem" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingHorizontal="16dp" android:paddingVertical="12dp"> <TextView android:id="@+id/tvTitle" android:layout_width="0dp" android:layout_height="wrap_content" android:text="@string/title_eg" android:textColor="@color/purple_200" android:textSize="14sp" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/tvDescription" android:layout_width="0dp" android:layout_height="wrap_content" android:text="@string/description_eg" android:textSize="12sp" android:textColor="@color/black" android:maxLines="2" android:justificationMode="inter_word" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvTitle" /> <TextView android:id="@+id/tvCategory" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@color/teal_700" android:padding="2dp" android:text="@string/category_eg" android:textColor="@color/white" android:textSize="10sp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvDescription" /> <TextView android:id="@+id/tvPublishedDate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/pub_date_eg" android:textSize="10sp" app:layout_constraintBottom_toBottomOf="@+id/tvCategory" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvDescription" /> </androidx.constraintlayout.widget.ConstraintLayout>
解决方法
在RecyclerView的Adapter类的onBindViewHolder方法中,为tvTitle设置点击事件,并通过控件的上下文获取Activity实例,调用supportFragmentManager执行Fragment事务。示例代码如下:
override fun onBindViewHolder(holder: ViewHolder, position: Int) { val item = dataList[position] holder.titleTextView.text = item.title holder.titleTextView.setOnClickListener { val subjectFragment = SubjectFragment() // 通过控件上下文获取Activity并执行Fragment事务 (holder.itemView.context as AppCompatActivity).supportFragmentManager.beginTransaction() .replace(R.id.newsFrameLayout, subjectFragment) .commit() } } // ViewHolder定义示例 class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val titleTextView: TextView = itemView.findViewById(R.id.tvTitle) }
内容的提问来源于stack exchange,提问作者Unish Raj.
相关产品推荐
相关产品推荐

