ListView在不刷新整个界面下,单独更新item

大家有没有遇到过在不刷新listview,即调用notifyDataSetChanged()的情况下单独更新item.下面带大家按照google采用的方式单独更新item

代码如下:

MainActivity

public class MainActivity extends Activity implements OnItemClickListener{
    ArrayList<String> list;
    ListView listview;
    ListViewAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listview=(ListView) findViewById(R.id.listview);
        init();
        adapter=new ListViewAdapter(list,this);
        listview.setAdapter(adapter);
        listview.setOnItemClickListener(this);
    }
    public void init(){
        list=new ArrayList<String>();
        list.add("the item 1");
        list.add("the item 2");
        list.add("the item 3");
        list.add("the item 4");
        list.add("the item 5");
        list.add("the item 6");
        ..........
    }
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long id) {
        adapter.updateSingleRow(listview,id);
    }
}


activity_main.xml 只有一个ListView控件。

ListViewAdapter:

public class ListViewAdapter extends BaseAdapter{
    ArrayList<String> list;
    Context context;
    public ListViewAdapter(ArrayList<String> list,Context context){
        this.list=list;
        this.context=context;
    }
    @Override
    public int getCount() {    
        return list.size();
    }
    @Override
    public Object getItem(int arg0) {
        return list.get(arg0);
    }
    @Override
    public long getItemId(int arg0) {
        return arg0;
    }
    @Override
    public View getView(int arg0, View convertView, ViewGroup viewGroup) {
        ViewHolder holder;
        if(convertView==null){
            convertView=LayoutInflater.from(context).inflate(R.layout.listview_item, null, false);
            holder=new ViewHolder();
            holder.textView=(TextView) convertView.findViewById(R.id.item_text);
            convertView.setTag(holder);
        }else{
            holder=(ViewHolder) convertView.getTag();
        }
        holder.textView.setText(list.get(arg0));
        return convertView;
    }
    
    class ViewHolder{
        TextView textView;
    }
    
    public void updateSingleRow(ListView listview,long id){
        int firstPosition=listview.getFirstVisiblePosition();
        int lasrPosition=listview.getLastVisiblePosition();
        for(int i=firstPosition;i<=lasrPosition;i++){
            if(listview.getItemIdAtPosition(i)==id){   //当传过来的id与遍历的id相同就更新
                  View view=listview.getChildAt(i-firstPosition);  //如果可见的第一个item不是0
                  list.remove(i);
                  list.add(i,"我在更新数据");
                  getView(i,view,null);
            }
        }
    }
}

这里解释下:

long id  表示item的id,这是与position是不同的概念。

listview.getFirstVisiblePosition(); 获取的屏幕上显示的第一条item的positon

listview.getLastVisiblePosition();  获取屏幕上显示的最后一条item的position

getView(i,view,null) 可以实现单独的更新,注意参数view.

至此就可以实现单独跟新item了,同样的采用notifyDataSetChanged()同样可以实现。


疑问:如果我加上Header和Footer还会实现相同的效果吗?

在MainActivity的listview.setAdapter(adapter)之前添加如下语句:

View header=LayoutInflater.from(this).inflate(R.layout.listview_header,null);    //很简单的布局
 View footer=LayoutInflater.from(this).inflate(R.layout.listview_footer,null);
 listview.addHeaderView(header);
  listview.addFooterView(footer);

测试图:


上拉刷新之后:


通过测试发现当点击刷新之后,滑动之后,更改数据出现下滑的现象.

主要原因是:添加header和footer之后第一个position的item变成了header, 最后一个position的item变成footer

假如我点击的第3个position的item,在前面有一个header和1个item,通过调用updateSingleRow(),遍历之后调用getView(i,view null),这里需要注意getView()中的position只对应arraylist的index,不包含header和footer,所以这里传进去的i包含了header,导致arraylist集体下移了,所以实际上更新的是第4个position的值,当滑动时肯定还原,变成第四个position更改数据。

解决方式:

list.remove(i-1);

list.add(i-1,"我在更新数据");  //加入i=3,那么改变的 是集合中第四条数据,所以必须减去1
getView(i-1,view,null);


最终的结果正确



问题:按照错误的方式,为什么我初次点击的时候,数据更改是对的,但是当我上拉之后数据才会变化,刚开始按照前面的逻辑应该也会错位?


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值