Kotlin中为AlertDialog列表项左侧添加图标的简易方法
实现方案
原生AlertDialog.Builder的setItems()方法默认使用系统内置的纯文本列表布局,本身不支持配置左侧图标,不要尝试反射修改系统布局做适配,不同Android版本的系统布局结构差异很大,很容易出现崩溃或错位问题。
最简单的无兼容问题的实现方式是用自定义ArrayAdapter配合极简的自定义列表项布局,全程不需要引入第三方库,代码量极小,和现有逻辑完全兼容:
第一步:创建列表项布局
在res/layout目录下新建dialog_item_with_icon.xml,布局对齐系统默认对话框的列表项样式:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="48dp" android:paddingStart="16dp" android:paddingEnd="16dp" android:gravity="center_vertical"> <ImageView android:id="@+id/iv_icon" android:layout_width="24dp" android:layout_height="24dp" android:layout_marginEnd="16dp" android:contentDescription="@null"/> <TextView android:id="@+id/tv_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16sp" android:textColor="?android:attr/textColorPrimary"/> </LinearLayout>
第二步:替换原有对话框逻辑
先定义简单的数据类绑定每个条目的文本和图标,从JSON解析数据时直接填充对应字段即可:
// 列表条目数据结构,网络图标可将iconRes替换为iconUrl字段 data class DialogOption( val text: String, val iconRes: Int )
替换原来的setItems逻辑,点击判断部分的代码不需要做大幅改动:
// 实际业务中这里替换为JSON解析出的列表数据 val options = mutableListOf( DialogOption("line 1", R.drawable.ic_line1), DialogOption("line 2", R.drawable.ic_line2), DialogOption("line 3", R.drawable.ic_line3), DialogOption("line x", R.drawable.ic_linex) ) val builder = android.app.AlertDialog.Builder(this@aplicacion) with(builder) { setTitle("List of options") setNegativeButton("Cancel") { dialog, _ -> dialog.dismiss() } setAdapter( object : ArrayAdapter<DialogOption>( this@aplicacion, R.layout.dialog_item_with_icon, R.id.tv_text, options ) { override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { val itemView = super.getView(position, convertView, parent) val currentItem = options[position] itemView.findViewById<ImageView>(R.id.iv_icon) .setImageResource(currentItem.iconRes) // 加载网络图标时,在这里用项目内的图片加载框架(Coil/Glide等)加载url即可 return itemView } } ) { _, position -> // 原有点击逻辑完全保留 val opcion = options[position].text when(opcion) { "line 1" -> function() // 其余选项分支直接在此追加 } } show() }
补充说明
- 该方案完全基于原生API实现,无额外依赖,兼容全版本Android系统,不会出现适配问题
- 布局尺寸、文字样式默认对齐系统AlertDialog原生风格,不会出现UI割裂
- 如果项目使用
AppCompatAlertDialog,仅需替换Builder类即可,其余逻辑完全通用,自动适配深色模式
内容的提问来源于stack exchange,提问作者oscarabilleira
相关产品推荐
相关产品推荐

