You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin:如何在AlertDialog中展示RecyclerView?

解决AlertDialog中RecyclerView结合DataBinding展示数据的问题

核心问题分析

你当前的问题有两个关键点:

  1. RecyclerView并没有内置android:adapter的DataBinding绑定属性,直接在布局里写android:adapter="@{ProgramAlertAdapter}"是无效的
  2. 主活动中没有正确获取弹窗布局的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 14:55:19