您的位置:首页 > 移动开发 > Android开发

android之notifyDataSetChanged失效

2016-04-10 20:06 489 查看
本文主要是记录一些零碎的东西

最近在使用ListView实现下拉刷新加载数据时,发现在使用simpleAdapter.notifyDataSetChanged();这个方法是没有效果,但是我日志输出时,我的数据确实是从服务器上加载到了, List<Map<String, Object>> listems 这里面也确实有数据,就是界面上没有显示出来,

在下拉刷新主要是通过 setOnTouchListener 实现,具体实现这里不记录了

我在给listview适配数据时使用simpleAdapter,需要显示Bitmap格式的图片,显示也有问题,这里顺便记录一下解决方案

private void setAdapter() {
/*SimpleAdapter的参数说明
* 第一个参数 表示访问整个android应用程序接口,基本上所有的组件都需要
* 第二个参数表示生成一个Map(String ,Object)列表选项
* 第三个参数表示界面布局的id  表示该文件作为列表项的组件
* 第四个参数表示该Map对象的哪些key对应value来生成列表项
* 第五个参数表示来填充的组件 Map对象key对应的资源一依次填充组件 顺序有对应关系
* 注意的是map对象可以key可以找不到 但组件的必须要有资源填充  因为 找不到key也会返回null 其实就相当于给了一个null资源
* 下面的程序中如果 new String[] { "name", "head", "desc","name" } new int[] {R.id.name,R.id.head,R.id.desc,R.id.head}
* 这个head的组件会被name资源覆盖
* */
mSimpleAdapter = new SimpleAdapter(
getActivity(),
listems,
R.layout.home_wares_list_item,
new String[] {"wares_name","wares_lovenum","wares_price","wares_img","wares_lovenum"},
new int[] {R.id.wares_name,R.id.wares_love_num,R.id.wares_price,R.id.wares_image,R.id.wares_love_num}
);
//  http://blog.csdn.net/y13872888163/article/details/6434001 //仅存取了Bitmap时在ListView中是无法显示图片的,我们需要对SimpleAdapter进行处理
//设置是否在应用也可以在这里面设置,重写getView,但那个是该所以的布局,我只想该关门的商户的显示,怎么破????
mSimpleAdapter.setViewBinder(new SimpleAdapter.ViewBinder() {

public boolean setViewValue(View view, Object data,
String textRepresentation) {
//判断是否为我们要处理的对象
if (view instanceof ImageView && data instanceof Bitmap) {
ImageView iv = (ImageView) view;
iv.setImageBitmap((Bitmap) data);
//                    Log.i("slack", "return true;");
return true;
} else {
//                    Log.i("slack","return false;");
return false;
}
}
});

mListView.setAdapter(mSimpleAdapter);
}
在加载数据时我不使用notifyDataSetChanged,直接调用setAdapter()重新配置数据也没有效果,郁闷坏了简直。

后来参考:http://www.tuicool.com/articles/aiiYzeR 天哪,居然是这么低级的错误,我一开始的写法

private void geneItems() {
listems= new ArrayList<Map<String, Object>>();
for(ShopProducts shopProducts : wares){
Map<String, Object> map = new HashMap<String, Object>();
map.put("wares_name",shopProducts.getName());
listems.add(map);
}
}
listems= new ArrayList<Map<String, Object>>();就是这句,删了就正常了,究其原因,每次new后都在堆空间里新开一片区域,listems都会指向新的内存地址,而notifyDataSetChanged会判断listems的数据是否变化,可是现在的listems指向都变了,所有不会执行任何操作

补充:内存中的栈(stack)、堆(heap)和静态区(static area)的用法

通常我们定义一个基本数据类型的变量,一个对象的引用,还有就是函数调用的现场保存都使用内存中的栈空间;而通过new关键字和构造器创建的对象放在堆空间;程序中的字面量(literal)如直接书写的100、"hello"和常量都是放在静态区中。

栈空间操作起来最快但是栈很小,通常大量的对象都是放在堆空间,理论上整个内存没有被其他进程使用的空间甚至硬盘上的虚拟内存都可以被当成堆空间来使用。

String str = new String("hello");

上面的语句中变量str放在栈上,用new创建出来的字符串对象放在堆上,而"hello"这个字面量放在静态区。

较新版本的Java(从Java 6的某个更新开始)中使用了一项叫"逃逸分析"的技术,可以将一些局部对象放在栈上以提升对象的操作性能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: