Android 解决 adapter.notifyDataSetChanged() 不起作用
2016-09-12 20:55
281 查看
转载请注明出处:http://blog.csdn.net/like_program/article/details/52517119
使用 Listview 的时候,给 adapter 的数据源 List 添加了新的数据,然后调用 adapter.notifyDataSetChanged(),发现 listview 并没有显示出新增的数据,但是遍历输出 List 中的元素,发现新增数据已经被添加到 List 中了,数据既然已经被添加到数据源中了,为什么 Listview 没有更新呢?
上网,查书,查了半天,终于在《Android群英传》中找到答案:
使用 adapter.notifyDataSetChanged() 时,必须保证传进 Adapter 的数据 List 是同一个 List
而不能是其他对象,否则无法更新 listview。
即,你可以调用 List 的 add(), remove(), clear(),addAll() 等方法,这种情况下,List 指向的始终是你最开始 new 出来的 ArrayList ,然后调用 adapter.notifyDataSetChanged() 方法,可以更新 ListView;但是如果你重新 new 了一个 ArrayList(重新申请了堆内存),那么这时候,List 就指向了另外一个 ArrayLIst,这时调用 adapter.notifyDataSetChanged() 方法,就无法刷新 listview 了。
说了这么多,不如来写个小 Demo 来感受下:
打开 Android Studio,新建一个 ListViewTest 项目。
activity_main.xml 代码如下:
布局文件很简单,从上至下,依次是 3 个按钮和一个 ListView。
MainActivity.java 代码如下:
MainActivity.java 代码也很简单,给四个按钮加上了按键监听,然后让 ListView 显示了 3 个数字,接下来,我们先点击 添加数据成功,删除数据,清除数据 ,这 3 个按钮,看 adapter.notifyDataSetChanged() 能否正常工作。
查看动态图,我们可以看到,点击这 3 个按钮,adapter.notifyDataSetChanged() 都可以正常工作,因为数据源始终是同一个 List,修改的只是 List 中的数据。
我们重新启动下 ListViewTest,再来看看点击 添加数据失败 按钮,adapter.notifyDataSetChanged() 能否正常工作。
查看 Logcat ,我们发现,数据源中的数据已经更新了:
但是查看动态图,我们可以看到,点击按钮,ListView 并没有更新数据,这时因为重新 new 了一个 ArrayList(重新申请了堆内存),那么这时候,List 就指向了另外一个 ArrayLIst,而要更新 ListView,必须保证传进 Adapter 的数据 List 是同一个 List 而不能是其他对象,所以 ListView 就无法更新了。
源码下载
使用 Listview 的时候,给 adapter 的数据源 List 添加了新的数据,然后调用 adapter.notifyDataSetChanged(),发现 listview 并没有显示出新增的数据,但是遍历输出 List 中的元素,发现新增数据已经被添加到 List 中了,数据既然已经被添加到数据源中了,为什么 Listview 没有更新呢?
上网,查书,查了半天,终于在《Android群英传》中找到答案:
使用 adapter.notifyDataSetChanged() 时,必须保证传进 Adapter 的数据 List 是同一个 List
而不能是其他对象,否则无法更新 listview。
即,你可以调用 List 的 add(), remove(), clear(),addAll() 等方法,这种情况下,List 指向的始终是你最开始 new 出来的 ArrayList ,然后调用 adapter.notifyDataSetChanged() 方法,可以更新 ListView;但是如果你重新 new 了一个 ArrayList(重新申请了堆内存),那么这时候,List 就指向了另外一个 ArrayLIst,这时调用 adapter.notifyDataSetChanged() 方法,就无法刷新 listview 了。
说了这么多,不如来写个小 Demo 来感受下:
打开 Android Studio,新建一个 ListViewTest 项目。
activity_main.xml 代码如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.listviewtest.MainActivity"> <Button android:id="@+id/btn_add_success" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="添加数据成功"/> <Button android:id="@+id/btn_add_fail" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="添加数据失败"/> <Button android:id="@+id/btn_delete" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="删除数据"/> <Button android:id="@+id/btn_clear" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="清空数据"/> <ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent"> </ListView> </LinearLayout>
布局文件很简单,从上至下,依次是 3 个按钮和一个 ListView。
MainActivity.java 代码如下:
package com.example.listviewtest; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.ListView; import android.widget.Toast; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity implements View.OnClickListener { public static final String TAG = "MainActivity"; /** * 添加成功 按钮 */ private Button btnAddSuccess; /** * 添加失败 按钮 */ private Button btnAddFail; /** * 删除数据 按钮 */ private Button btnDelete; /** * 清空数据 按钮 */ private Button btnClear; private ListView listView; /** * 适配器的数据源 */ private List<Integer> dataList; /** * 适配器 */ private ArrayAdapter adapter; /** * 添加的数据 */ private int addNumber = 3; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 实例化控件 btnAddSuccess = (Button) findViewById(R.id.btn_add_success); btnAddFail = (Button) findViewById(R.id.btn_add_fail); btnDelete = (Button) findViewById(R.id.btn_delete); btnClear = (Button) findViewById(R.id.btn_clear); listView = (ListView) findViewById(R.id.listview); // 设置点击监听 btnAddSuccess.setOnClickListener(this); btnAddFail.setOnClickListener(this); btnDelete.setOnClickListener(this); btnClear.setOnClickListener(this); // 初始化数据 initData(); // 创建适配器 adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout .simple_list_item_1, dataList); // 设置适配器 listView.setAdapter(adapter); } /** * 初始化数据源 */ private void initData() { dataList = new ArrayList<>(); for (int i = 0; i < 3; i++) { dataList.add(i); } } @Override public void onClick(View v) { switch (v.getId()) { // 如果点击的是 添加数据成功 按钮 case R.id.btn_add_success: // 添加数据 成功 dataList.add(addNumber); adapter.notifyDataSetChanged(); Toast.makeText(MainActivity.this, "添加成功", Toast.LENGTH_SHORT).show(); Log.d(TAG, "数据源:" + dataList.toString()); break; // 如果点击的是 添加数据失败 按钮 case R.id.btn_add_fail: dataList = new ArrayList<>(); initData(); // 添加数据失败 dataList.add(addNumber); adapter.notifyDataSetChanged(); Toast.makeText(MainActivity.this, "添加失败", Toast.LENGTH_SHORT).show(); Log.d(TAG, "数据源:" + dataList.toString()); break; // 如果点击的是 删除数据 按钮 case R.id.btn_delete: if (!dataList.isEmpty()) { // 删除 list 最后一个数据 int deleteNumber = dataList.get(dataList.size() - 1); dataList.remove(deleteNumber); adapter.notifyDataSetChanged(); Toast.makeText(MainActivity.this, "删除数据", Toast.LENGTH_SHORT).show(); Log.d(TAG, "数据源:" + dataList.toString()); } else { Toast.makeText(MainActivity.this, "已经没有数据了", Toast.LENGTH_SHORT).show(); Log.d(TAG, "数据源:" + dataList.toString()); } break; // 如果点击的是 清空数据 按钮 case R.id.btn_clear: // 清空数据 dataList.clear(); adapter.notifyDataSetChanged(); Toast.makeText(MainActivity.this, "清空数据", Toast.LENGTH_SHORT).show(); Log.d(TAG, "数据源:" + dataList.toString()); break; } } }
MainActivity.java 代码也很简单,给四个按钮加上了按键监听,然后让 ListView 显示了 3 个数字,接下来,我们先点击 添加数据成功,删除数据,清除数据 ,这 3 个按钮,看 adapter.notifyDataSetChanged() 能否正常工作。
查看动态图,我们可以看到,点击这 3 个按钮,adapter.notifyDataSetChanged() 都可以正常工作,因为数据源始终是同一个 List,修改的只是 List 中的数据。
我们重新启动下 ListViewTest,再来看看点击 添加数据失败 按钮,adapter.notifyDataSetChanged() 能否正常工作。
查看 Logcat ,我们发现,数据源中的数据已经更新了:
但是查看动态图,我们可以看到,点击按钮,ListView 并没有更新数据,这时因为重新 new 了一个 ArrayList(重新申请了堆内存),那么这时候,List 就指向了另外一个 ArrayLIst,而要更新 ListView,必须保证传进 Adapter 的数据 List 是同一个 List 而不能是其他对象,所以 ListView 就无法更新了。
源码下载
相关文章推荐
- Android中BluetoothAdapter.startDiscovery方法搜索蓝牙设备不起作用的解决办法
- android webview goBack不起作用的解决方法
- android LinearLayout设置selector不起作用解决
- Android系统修改Hosts文件不起作用解决方法
- 有关ViewPager的使用及解决Android下ViewPager和PagerAdapter中调用notifyDataSetChanged失效的问题
- android-继承BaseAdapter--自定义适配器,getView执行多次的解决方法
- 非常奇怪的问题:动态创建的View设置Visibility不起作用(Android,已解决)
- 【Android】自定义ListView的Adapter报空指针异常解决方法
- 有关ViewPager的使用及解决Android下ViewPager和PagerAdapter中调用notifyDataSetChanged失效的问题
- 有关ViewPager的使用及解决Android下ViewPager和PagerAdapter中调用notifyDataSetChanged失效的问题
- 有关ViewPager的使用及解决Android下ViewPager和PagerAdapter中调用notifyDataSetChanged失效的问题
- 解决Android下ViewPager和PagerAdapter中调用notifyDataSetChanged失效问题
- android 中onItemClickListener不起作用解决办法
- android下修改hosts文件不起作用(无效)的解决办法
- android listview继承BaseAdapter,自定义的适配器,getView方法执行多组循环解决方式
- android webview goBack不起作用的解决方法
- android:layout_marginRight 不起作用解决方法
- android PagerAdapter notifyDataSetChanged() 无法更新数据问题解决
- 在Android开发中替换资源图片不起作用的解决方法
- 【Android】自定义ListView的Adapter报空指针异常解决方法