Android学习总结之—ListView调用notifyDataSetChanged无刷新

最近在利用ListView在做数据刷新的时候,遇到调用notifyDataSetChanged方法不管
用,于是打印了数据适配器中的数据发现确实数据是增加了,但是调用却没有生效。让我一直想去看看notifyDataSetChanged的工作原理以及实现流程,当然由于项目紧还是上网查了下,原来是我犯了非常低级的错误导致无法刷新。可是我却蒙在鼓里毫无察觉。下面我就讲讲我到底犯了什么“错”:

1.适配器


public class MyAdapter extends BaseAdapter {
	ArrayList<T> list;
	LayoutInflater inflater;

	public MyAdapter(Context context, ArrayList<T> list) {
		this.list = list;
		this.inflater = LayoutInflater.from(context);
	}


通常我们会向如上创建一个数据适配器,并会向如下方式设置ListView的数据适配器:


	adapter = new MyAdapter(this, list);
	
<span style="white-space:pre">	</span>listview.setAdapter(adapter);

2.数据源

	List list = new ArrayList<T>();
	...
	// 刷新ListView
	void updateView(){
		list = queryList();
		adapter.notifyDataSetChanged();
	}
	
	// 设置数据源
	List queryList(){
		...
	}

看到如上方法我觉得也算是也算是比较标准的设置数据源的方式了,可是就是因为这个流程。下面我们来用图的方式说明:


可能这个图看上去有点乱,其实就是给BaseAdapter设置数据源一开始给是适配器设置了数据源1, 外部list的也是指向数据源1。

再后来调用updateView()方法的时候给list又重新设置了一个内存区,那么他就指向了数据源2,可是BaseAdapter中的List数据还是原来的数据源1。

当我们在调用notifyDataSetChanged()方法的时候不刷新也就很容易理解了。

正确的方式:

	List list = new ArrayList<T>();
	...
	// 刷新ListView
	void updateView(){
		list = list.addAll(queryList());
		adapter.notifyDataSetChanged();
	}
	// 设置数据源
	List queryList(){
		...
	}


3.本质

其实说了这么多无非就是我们在大学学C语言的时候老师强调了无数遍的形参实参的关系,以及指针的方面的东西,java虽然没有指针,但是引用也是可以类比指针的。引用的改变以及引用指向的内存中数据改变,这些问题都是我们要十分注意的。就好比StringBuffer和String的关系,当数据发生改变前者可以保值原有的引用而后者引用已经发生了改变,引用的改变其实也就是指向的内存空间的地址发生的改变。

总结:

其实讲了这么多可能有人觉得其实这不就是一个简单的引用错乱的问题吗,其实在实际开发中类的相互引用以及关系会变的错中复杂,可能一个小小的程序我们能很好的管理之间的调用,但是多了我们有时会很难把控。虽然java没有指针的概念,但是程序内存方面的知识还是不得不去研究一下的好,这样对于我们来说程序变得可控了。我也一直觉得c/c++都是有必要去学习的,其实不是去学语法什么的更多地是能了解底层。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 开发中,ListView 是一个常用的控件,用于展示列表数据。当数据源发生改变时,我们可以通过调用 adapter 的 notifyDataSetChanged 方法来通知 ListView 刷新数据。不过有时候,调用该方法后 ListView 并没有刷新成功,这是为什么呢? 通常情况下,adapter 调用 notifyDataSetChanged 方法后 ListView 会自动刷新,但有一些情况下会出现刷新失败的情况,主要原因如下: 1. 数据源未更新 notifyDataSetChanged 方法只能刷新 adapter 中的数据源,如果数据源没有更新,那么 ListView 就无法刷新。因此,在调用该方法之前,必须要确保 adapter 中的数据源已经更新。 2. ListView 高度计算错误 当 ListView 的高度计算错误时,可能会导致刷新失败。当 ListView 的高度设置为 wrap_content 时,它的高度会根据内容自适应,这时如果数据源发生变化,ListView 的高度也会发生变化,但是 ListView 并不会自动刷新,需要手动调用 requestLayout 方法来重新计算布局。 3. ListView 处于滚动状态 当 ListView 处于滚动状态时,调用 notifyDataSetChanged 方法可能会失效。因为在滚动过程中,ListView 的布局已经被固定,此时调用 notifyDataSetChanged 方法并不会改变布局,只有当滚动停止后才会刷新数据。如果需要在滚动状态下刷新数据,可以尝试使用 notifyDataSetInvalidated 方法。 综上所述,ListView adapter 调用 notifyDataSetChanged 方法无效的原因可能是数据源未更新、ListView 高度计算错误或者 ListView 处于滚动状态。需要根据具体情况进行分析和解决。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值