首先看下要实现的效果,点击item时改变按钮的选中状态
常规的做法是:1.生成一个map对象
2.在点击item的时候,用map存储position和该item是否被选中的状态(true / false)
3.在adapter的getview的方法里通过position在map中取得状态,进行判断复选框的选中状态。
4,调用listview的 notifydatasetchanged()方法刷新。
- 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;
- }
但是:每次点击一次,都会刷新全部的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;
- }