Adapter通常的写法都是用一个成员变量Data持有着对数据的引用,然后在active中对data数据进行修改即可更新界面显示。
但是有些情况下可能无法更新。
网上有很多,具体分为(引用别人的分析):
List
SongAdapter mSongAdapter = new SongAdapter(getApplicationContext(), mSongVOs);//用数据初始化适配器
lvMusicList.setAdapter(mSongAdapter);//为ListView绑定适配器
//情况1.
可以刷新Listview数据
mSongVOs.remove(x);
mSongAdapter.notifyDataSetChanged();
//情况2.不刷新
mSongVOs=getSongs(B);//数据B
mSongAdapter.notifyDataSetChanged();
//情况3.可以刷新
mSongVOs.clear();
mSongVOs.addAll(helper.getAudios());
mSongAdapter.notifyDataSetChanged();
之后ListView的刷新都是通过Adapter.getItem()等方法进行更新,而这些方法访问的数据时这个mData指向的数据。如果这个数据不变,那么notifyDataSetChanged自然不会刷新。
在情况1、3中,局部变量mSongVOs和SongAdapter的成员变量mData指向的是同一块内存地址,即数据A,因此mSongVOs修改A后,notifyDataSetChanged通过mData再访问A时发现数据变了,所以就更新了ListView。
在情况2中,局部变量mSongVOs通过getSong(B)获取新数据B,实际是mSongVOs指向了内存中另外一块地址B,而此时mData指向的仍然是A。因此notifyDataSetChanged观察到A始终没有变化,因此不刷新。
所以,情况2,并不是Adapter“数据变了却不刷新”,而是“数据根本没变”。
而网上说重新对adapter绑定即可刷新,实际上就是重新绑定了成员变量mData,因此可以刷新。
情况2、3的业务逻辑是换了一整批数据,编程上情况2似乎是很直观和合理的,但是得注意了,得用第三种写法。
还有一种情况:
最终原因就是数据引用导致:adapter里面针对A进行多层引用(adapter基类中又有新数据生产),即时你在前台页面更新了A,然后在在adapter的处理中数据还是没变。怎么办?
那就在基类中写一个更新方法,来触发更新。
比如:
/**
* 更新在线状态方法
* @param user
* @param flag
*/
public void UpdateChangePostion(String user,boolean flag)
{
//nodes就是传递进来的数据副本,下面的方法直接对Nodes中的数据进行修改来达到更新重绘
//这种情况,你要注意你的数据库与内存的联系,各自处理。
for(Node node:Nodes)
{
if(node.getUserName().equals(user))
{
node.setStatus(flag);
}
}
notifyDataSetChanged();
}
具体的方法可以自己写,这个只是思路。