解决Listview局部刷新,item地址复用所产生的问题

首先看下要实现的效果,点击item时改变按钮的选中状态

                                      

常规的做法是:1.生成一个map对象

                            2.在点击item的时候,用map存储position和该item是否被选中的状态(true / false)

                            3.在adapter的getview的方法里通过position在map中取得状态,进行判断复选框的选中状态。

                            4,调用listview的 notifydatasetchanged()方法刷新。


  1. private HashMap<Integer, Boolean> map = new HashMap<Integer, Boolean>(){};

  2. lv.setOnItemClickListener(new OnItemClickListener(){

  3.     @Override
  4.     public void onItemClick(AdapterView<?> parent, View currentView, int position, long id) {
  5.   
  6.          boolean checkBoxState = !map.get(position);
  7.          map.put(position, checkBoxState);
  8.          adapter.notifyDataSetChanged();
  9.     }
  10. });


  1. @Override
  2. public View getView(int position, View currentView, ViewGroup parent) {

  3.     ViewHolder viewHolder;
  4.     if(currentView == null){
  5.       
  6.        currentView = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_lv, null);         
  7.        viewHolder = new ViewHolder();
  8.        viewHolder.m_tv = (TextView) currentView.findViewById(R.id.m_tv);          
  9.        viewHolder.m_cb = (CheckBox) currentView.findViewById(R.id.m_cb);        
  10.        currentView.setTag(viewHolder);   
  11.     }else{      
  12.        viewHolder = (ViewHolder) currentView.getTag();   
  13.     }
  14.     viewHolder.m_tv.setText(getItem(position));
  15.     // 复选框更改状态
  16.     boolean checkBoxState = map.get(position);
  17.     viewHolder.m_cb.setChecked(checkBoxState);
  18.     return currentView;
  19. }


但是:每次点击一次,都会刷新全部的item, 这样性能太差

所以尼,我们采用了局部刷新的功能,

           1.在点击item的时候,根据传递过来的view获取相应的控件,然后改变状态,这样就不需要再用notifydatasetchanged()了,这样是局部刷新。性能比较好

但是:因为我们用了viewholder,所以地址会出现重复,以上拉滑动,因为用了同一个地址,所以我们点击了item2时,一下拉,item12也是选中的状态。


那怎么办尼?在网上也看了一些,Listview局部刷新,复用重复的问题,但是没有什么靠谱的。所以啊,解决办法就是

            1.生成一个map对象
            2.在点击item的时候,用map存储position和该item是否被选中的状态(true / false)(解决复用重复问题)
            3. 在点击item的时候,根据传递过来的view获取相应的控件,然后改变状态  (局部刷新)
            4.在adapter的getview的方法里通过position在map中取得状态,进行判断复选框的选中状态。(解决复用重复问题)

以下是代码

private HashMap<Integer, Boolean> map = new HashMap<Integer, Boolean>(){};

lv.setOnItemClickListener(new OnItemClickListener(){
     @Override      public void onItemClick(AdapterView<?> parent, View currentView, int position, long id) {
                   CheckBox cb = (CheckBox)view.findviewbyid(R.id.m_cb); // 获取点击的item的控件。           boolean checkBoxState = !map.get(position); // 如果之前是选中,那么再点就是取消,所以取反。           map.put(position, checkBoxState);    // 为啥还要记录状态尼,原因很简单,因为啊,地址重用,所以状态会重复,所以点击时,走局部刷新,                                              // 拉时还是需要走getView 判断状态的。这样就不会发生重复了。                                cb.setCheck(checkBoxState);  // 因为已经获取了item的view了,直接就能改动了,所以不需要再刷新了,局部刷新功能已经实现      } });
@Override public View getView(int position, View currentView, ViewGroup parent) {
    ViewHolder viewHolder;     if(currentView == null){               currentView = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_lv, null);                 viewHolder = new ViewHolder();        viewHolder.m_tv = (TextView) currentView.findViewById(R.id.m_tv);                   viewHolder.m_cb = (CheckBox) currentView.findViewById(R.id.m_cb);                currentView.setTag(viewHolder);        }else{              viewHolder = (ViewHolder) currentView.getTag();         }
    viewHolder.m_tv.setText(getItem(position));     // 复选框更改状态     boolean checkBoxState = map.get(position);     viewHolder.m_cb.setChecked(checkBoxState);     return currentView;
}
private HashMap<Integer, Boolean> map = new HashMap<Integer, Boolean>(){};
lv.setOnItemClickListener(new OnItemClickListener(){
     @Override      public void onItemClick(AdapterView<?> parent, View currentView, int position, long id) {
             boolean checkBoxState = !map.get(position);           map.put(position, checkBoxState);           adapter.notifyDataSetChanged();
     } });
@Override public View getView(int position, View currentView, ViewGroup parent) {     ViewHolder viewHolder;     if(currentView == null){               currentView = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_lv, null);                 viewHolder = new ViewHolder();        viewHolder.m_tv = (TextView) currentView.findViewById(R.id.m_tv);                   viewHolder.m_cb = (CheckBox) currentView.findViewById(R.id.m_cb);                currentView.setTag(viewHolder);        }else{              viewHolder = (ViewHolder) currentView.getTag();         }
    viewHolder.m_tv.setText(getItem(position));     // 复选框更改状态     boolean checkBoxState = map.get(position);     viewHolder.m_cb.setChecked(checkBoxState);     return currentView;
}
发布了30 篇原创文章 · 获赞 78 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/u010302765/article/details/50403117