Android Kotlin中更新ListView时调用notifyDataSetChanged()导致应用崩溃求助
你遇到的这个IllegalStateException错误其实很常见,核心问题出在ArrayAdapter的构造参数使用不对,跟notifyDataSetChanged()本身关系不大——崩溃是在ArrayAdapter尝试绑定数据的时候触发的,只是刚好在调用notifyDataSetChanged后暴露出来而已。
先给你拆解一下错误原因:
当你用ArrayAdapter(this, R.layout.item_view, itemList)这个构造函数时,ArrayAdapter默认认为你传入的R.layout.item_view是一个单独的TextView控件布局(根节点必须是TextView)。如果你的item_view.xml是一个包含其他容器(比如LinearLayout、RelativeLayout)的布局,ArrayAdapter找不到它默认需要的TextView来显示数据,就会抛出ArrayAdapter requires the resource ID to be a TextView这个异常。
下面给你两种直接可用的修复方案,根据你的需求选就行:
方案一:用系统默认布局快速解决
如果你的列表项只需要显示简单文本,完全可以直接用Android系统自带的标准列表项布局,这样不用改自定义布局,直接修改ArrayAdapter的初始化代码:
// 替换原来的adapter初始化代码 adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, itemList)
android.R.layout.simple_list_item_1是系统专门为ArrayAdapter准备的布局,内部就是一个TextView,能直接适配ArrayAdapter的默认绑定逻辑。
方案二:保留自定义布局的修复方式
如果你一定要用自己写的item_view.xml,需要做两个小调整:
- 确保你的
item_view.xml里有一个带明确ID的TextView(比如给它设ID为tv_item_text),示例布局代码参考:
<!-- res/layout/item_view.xml --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingVertical="12dp" android:paddingHorizontal="16dp"> <TextView android:id="@+id/tv_item_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="16sp"/> </LinearLayout>
- 改用ArrayAdapter的另一个构造函数,明确指定布局中用来显示文本的TextView的ID:
// 第三个参数传入你自定义布局中TextView的ID adapter = ArrayAdapter(this, R.layout.item_view, R.id.tv_item_text, itemList)
这样ArrayAdapter就知道要把列表数据绑定到哪个TextView上了,不会再报错。
顺便提个小细节
你的afterTextChanged方法里还有个小bug:你定义了val newItem = "test",但往列表里加的是字符串"newItem"(带引号的固定文本),不是变量newItem,这样每次添加的都是"newItem"而不是你定义的"test",可以改成:
override fun afterTextChanged(s: Editable?) { val newItem = "test" // 这里以后可以换成扫描到的条码内容,比如s.toString().trim() if (newItem.isNotEmpty()) { itemList.add(newItem) // 用变量newItem,不是字符串"newItem" adapter.notifyDataSetChanged() editText.requestFocus() // 可选:添加完成后清空输入框,方便下次扫描 // editText.setText("") } }
按上面的方法改完,再运行应该就不会崩溃了,列表也能正常添加新的条码项~
内容来源于stack exchange

