您的位置:首页 > 其它

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

2015-08-21 19:33 260 查看
大家有没有遇到过在不刷新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);

最终的结果正确



问题:按照错误的方式,为什么我初次点击的时候,数据更改是对的,但是当我上拉之后数据才会变化,刚开始按照前面的逻辑应该也会错位?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: