RecyclerView Adapter调用Fragment方法报错:lateinit属性textView未初始化
崩溃原因
你崩溃的核心问题是在Adapter中主动新建了SwipeFragment实例,这个全新的Fragment实例没有被添加到FragmentManager,也没有走onCreateView等生命周期流程,所以你声明的lateinit var textView从来没有被初始化,调用updateTextView的时候自然会抛出未初始化异常。
而且直接在Adapter里持有Fragment实例属于强耦合,不符合组件职责分离的设计原则,也容易引发内存泄漏。
正确实现方案(接口回调)
通过接口回调实现Adapter和Fragment的通信,完全解耦两者的逻辑,步骤如下:
1. 定义回调接口
先新建一个回调接口,用于通知滑动事件:
interface OnItemSwipedListener { fun onSwiped(position: Int) }
2. 修改SwipeAdapter逻辑
删除Adapter内部新建Fragment的代码,改为通过构造函数传入回调实例:
class SwipeAdapter internal constructor( private val mCandidatesArrayList: ArrayList<SwipeCandidate>, // 新增回调参数 private val swipedListener: OnItemSwipedListener ) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { fun createHelperCallback(): ItemTouchHelper.Callback { return object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) { override fun onMove( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean { return false } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) { val position = viewHolder.bindingAdapterPosition // 触发回调,把事件抛给外部处理 swipedListener.onSwiped(position) } } } // 剩下的Adapter原有逻辑保持不变 }
3. 修改SwipeFragment逻辑
让Fragment实现回调接口,创建Adapter时把自身作为回调传入即可:
class SwipeFragment : Fragment(), OnItemSwipedListener { private lateinit var textView : TextView override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { // 注意你原来的代码漏了inflate布局获取root,这里补全逻辑 val root = inflater.inflate(R.layout.your_fragment_layout, container, false) textView = root.findViewById(R.id.textview) // 创建Adapter时传入当前Fragment作为回调实例 val adapter = SwipeAdapter(你的列表数据, this) // 后续给RecyclerView设置Adapter、绑定ItemTouchHelper的逻辑保持不变 return root } fun updateTextView() { textView.setText("Hello") } // 实现回调接口的方法 override fun onSwiped(position: Int) { // 这里直接调用更新TextView的方法即可 updateTextView() // 如果需要用到滑动的position参数也可以直接使用 } }
内容的提问来源于stack exchange,提问作者The Fluffy T Rex
相关产品推荐
相关产品推荐

