自定义ArrayAdapter时notifyDataSetChanged()失效及Spinner选值Cursor获取问题
嘿,我来帮你搞定这两个Android开发的问题!
问题1:自定义ArrayAdapter的notifyDataSetChanged()无法正常工作
这个问题我踩过不少坑,通常都是这几个原因导致的,对应解决办法如下:
- 没有操作Adapter持有的原数据源对象:很多人更新数据时会直接new一个新的List替换旧的,比如
mList = new ArrayList<>(newData),但Adapter绑定的还是原来的List对象,这时候notify自然没用。解决办法是直接修改原List(比如mList.clear(); mList.addAll(newData)),再调用notifyDataSetChanged();或者在自定义Adapter里加一个setData(List<T> newData)方法,内部替换数据源并调用notify。 - 自定义Adapter的核心方法重写错误:如果你的Adapter重写了
getCount()、getItem()这些方法,但返回的不是当前数据源的真实状态(比如getCount()硬写了固定数值),那UI肯定不会更新。一定要确保这些方法都是基于当前的数据源计算的,比如getCount()返回mData.size()。 - 在子线程调用notify:
notifyDataSetChanged()必须在UI线程执行,如果是在子线程更新数据后直接调用,大概率不生效。可以用runOnUiThread(() -> adapter.notifyDataSetChanged())或者Handler切换到主线程再调用。 - 数据源是不可变集合:比如用
Arrays.asList()生成的List是固定大小的,无法添加/删除元素,修改时不仅会报错,notify也没用。这种情况要把它转成可变的ArrayList:new ArrayList<>(Arrays.asList(yourArray))。
问题2:获取Spinner选中元素的Cursor
从你的代码片段来看,HOperListAdapter应该是继承自CursorAdapter(因为构造参数里传了hopers这个Cursor),那要获取选中位置的Cursor很简单,直接在OnItemSelectedListener里处理就行:
spOeManoDeObra.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { // 从Spinner的Adapter中获取选中位置的Cursor Cursor selectedCursor = (Cursor) parent.getItemAtPosition(position); // 然后就可以从Cursor中读取你需要的数据了,比如获取名称列 if (selectedCursor != null && !selectedCursor.isClosed()) { int nameColumnIndex = selectedCursor.getColumnIndex("lblLaNombre"); // 这里替换成你实际的列名 String selectedName = selectedCursor.getString(nameColumnIndex); // 后续处理逻辑... } } @Override public void onNothingSelected(AdapterView<?> parent) { // 未选中时的处理,比如设置默认值或者提示 } });
这里要注意几个细节:
- 不要手动关闭这个Cursor,因为它是由
HOperListAdapter持有管理的,关闭会导致Adapter报错。 - 如果你的Adapter是用CursorLoader加载的,要确保Cursor的生命周期和组件(Activity/Fragment)绑定好,避免出现Cursor已关闭的异常。
- 一定要加非空判断,防止特殊情况(比如Spinner初始化时没有数据)导致空指针。
内容的提问来源于stack exchange,提问作者alGhul7
相关产品推荐
相关产品推荐

