ListView用单行刷新取代notifyDataSetChanged

一.没有head view和footview的情况

1.谷歌的方案

private void updateSingleRow(ListView listView, long id) {  

        if (listView != null) {  
            int start = listView.getFirstVisiblePosition();  
            for (int i = start, j = listView.getLastVisiblePosition(); i <= j; i++)  
                if (id == ((Messages) listView.getItemAtPosition(i)).getId()) {  
                    View view = listView.getChildAt(i - start);  
                    getView(i, view, listView);  
                    break;  
                }  
        }  
    }  

  代码解释:
1. 我们看一下adapter的getView方法,我们要进行单条刷新就要手动调用这个方法。public View getView(int position, View convertView, ViewGroup parent)
getView方法的第三个参数很好确定,就是你的listview。
2. getFirstVisiblePosition(),该方法获取当前状态下list的第一个可见item的position。
3. getLastVisiblePosition(),该方法获取当前状态下list的最后一个可见item的position。
4. getItemAtPosition(int position),该方法返回当前状态下position位置上listView的convertView

ps:这里的convertView是复用的,也就是说不管position的值是多大(这个要看你整个list有多大),converView的个数应该始终是屏幕上能显示的list的条数那么多。
所以,我们通过从getFirstVisiblePosition的值到getLastVisiblePosition的值之间的listitem和需要进行更新的条件(比如id)进行比较确定哪一个是要更新的(如果不在当前可是范围内也就没有必要更新了,等list拉动的时候自然就会更新出来)

2.我的方案1改进

  你要把listview的每个item都加上一个标记,实体也要加上一个标记,这样就可以保证数据和item一一对应。同时在adapter的getview方法中,把每一个view使用arraylist都缓存起来,刷新时去遍历缓存的view,判断哪个缓存的view的标记和实体的标记对应,就给这个view重新赋值一遍即可。

3.我的方案2改进

private void updateSingleRow(Message message) {
        for (int i = 0; i < mListView.getChildCount(); i++) {
            View view =  mListView.getChildAt(i);
            if (view.getPosition() == message.getPosition()) {
                mDemoAdapter.getView(message.getPosition(), view, mListView);
                break;
            }
        }

  代码解释:
  这里主要是你要把listview的每个item都加上一个标记,实体也要加上一个标记,这样就可以保证数据和item一一对应。我们改变了实体的属性,如果该数据正显示在当前页面上,那我们就调用getview方法来刷新它,否则在我们滚动listview的时候,系统会自动帮我们去调用getview方法来刷新列表。

二.有head view和footview的情况

1.谷歌的方案改进

  可以应对这种情况,不过比较难以处理,我当时尝试了接近1h还是没有很好的解决这个问题。

2.我的方案1改进

  不存在这个问题

3.我的方案2改进

  比较容易处理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值