Android Kotlin:如何在AlertDialog中展示RecyclerView?
解决AlertDialog中RecyclerView结合DataBinding展示数据的问题
核心问题分析
你当前的问题有两个关键点:
- RecyclerView并没有内置
android:adapter的DataBinding绑定属性,直接在布局里写android:adapter="@{ProgramAlertAdapter}"是无效的 - 主活动中没有正确获取弹窗布局的DataBinding实例,导致无法通过
binding.programAlertAdapter设置适配器
修正步骤及代码
1. 修正弹窗布局(program_of_today_alert_dialog.xml)
去掉布局里无效的android:adapter属性,同时调整变量名遵循小驼峰命名规范:
<data> <variable name="programAlertAdapter" type="com.gorkemersizer.gymapp.ui.adapters.ProgramAlertAdapter" /> </data> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rvAlertProgram" android:layout_width="0dp" android:layout_height="0dp" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
2. 修正主活动代码
正确获取弹窗布局的DataBinding实例,完成适配器的设置:
// 创建适配器 val adapter = ProgramAlertAdapter(it) // 获取弹窗布局的DataBinding对象(用DataBindingUtil.inflate替代直接LayoutInflater) val binding = ProgramOfTodayAlertDialogBinding.inflate(LayoutInflater.from(this)) // 设置适配器变量 binding.programAlertAdapter = adapter // 给RecyclerView手动绑定适配器 binding.rvAlertProgram.adapter = adapter // 构建并显示弹窗 AlertDialog.Builder(this, R.style.MyDialogTheme) .setView(binding.root) .setTitle("Programs of Today") .show()
3. 优化适配器代码(可选但推荐)
去掉冗余的Context参数,从ViewHolder的parent获取Context,降低内存泄漏风险:
class ProgramAlertAdapter( var programList: List<Program> ) : RecyclerView.Adapter<ProgramAlertAdapter.CardViewHolder>() { inner class CardViewHolder(binding: AlertProgramCardDesignBinding): RecyclerView.ViewHolder(binding.root) { val binding: AlertProgramCardDesignBinding = binding } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CardViewHolder { val layoutInflater = LayoutInflater.from(parent.context) val binding = AlertProgramCardDesignBinding.inflate(layoutInflater, parent, false) return CardViewHolder(binding) } override fun onBindViewHolder(holder: CardViewHolder, position: Int) { holder.binding.programObject = programList[position] // 强制触发数据绑定,避免数据更新延迟 holder.binding.executePendingBindings() } override fun getItemCount() = programList.size }
4. 卡片布局(alert_program_card_design.xml)
原有代码逻辑正常,保持原样即可:
<data> <variable name="programObject" type="com.gorkemersizer.gymapp.data.entity.Program" /> </data> <androidx.cardview.widget.CardView ...> <TextView android:text="@{programObject.program_name}" ... /> <!-- 其他展示控件 --> </androidx.cardview.widget.CardView>
补充:自定义BindingAdapter实现布局直接绑定(可选)
如果想通过DataBinding直接在布局里绑定适配器,可以自定义一个BindingAdapter:
@BindingAdapter("android:adapter") fun setRecyclerViewAdapter(recyclerView: RecyclerView, adapter: RecyclerView.Adapter<*>?) { recyclerView.adapter = adapter }
定义后就可以在弹窗布局里直接使用android:adapter="@{programAlertAdapter}",无需在代码里手动设置binding.rvAlertProgram.adapter = adapter。
内容的提问来源于stack exchange,提问作者Sezai
相关产品推荐
相关产品推荐

