自定义SimpleAdapter实现长按多选操作

1.SimpleAdapter部分函数介绍

重要方法介绍

1.abstract View getView (int position, View convertView, ViewGroup parent)

获取数据集中指定位置的数据并显示数据到视图中。
数据映射方法

  1. inflate(int, android.view.ViewGroup, boolean)
  2. findViewById(int)

注意:convertView会尽可能的复用已经存在的视图,即会存在相同的控件。
只有部件出现在视窗才会调用getView初始化视图

2.void notifyDataSetChanged()

通知所有视图更新数据

2.多选操作的实现(CheckBox)

最好不要通过HashMap<Integer,CheckBox>获取checkbox然后调用setChecked(boolean)来设置checked属性,因为getView会复用就视图导致HashMap里会有相同值(CheckBox)。所以我借助getView设置checkBox的visibility和checked属性,步骤如下:

  1. 修改数据集的数据,例如关于isChecked,isVsible等data数据
  2. 通过adapter.notifyDataSetChanged()更新视图。
  3. getView刷新视图

主要代码如下:

List<Integer> selectPos;

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    convertView = super.getView(position, convertView, parent);
    //获取相应View中的Checkbox对象,其他的数据通过super映射
    CheckBox checkBox = convertView.findViewById(R.id.diary_item_check);
    //设置checkbox的checked属性
    if(selectedPos.containsKey(position))
        checkBox.setChecked(true);
    //如果是多选,就显示checkbox
    if((boolean)list.get(position).get(IS_MULTI_SELECT)){
        setCheckBoxIsVisible(checkBox, true);
    }else {
        setCheckBoxIsVisible(checkBox, false);
    }

    /*
     * 在ListView中点击每一项的处理
     * 如果CheckBox未选中,则点击后选中CheckBox,并将数据添加到selectPos中
     * 如果CheckBox选中,则点击后取消选中CheckBox,并将数据从selectPos中移除
     * 非多选会通过Intent传递数据,启动新的activity
     */
    convertView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // 处于多选模式
            if (isMultiSelect) {
                if (selectedPos.containsKey(position)) {
                    checkBox.setChecked(false);
                    selectedPos.remove(position);
                } else {
                    checkBox.setChecked(true);
                    selectedPos.put(position, noteEntities.get(position).getNoteId());
                }
            }else {
                Intent intent = new Intent(getActivity(), EditNoteActivity.class);
                Bundle bundle = new Bundle();
                bundle.putSerializable("note", noteEntities.get(position));
                intent.putExtras(bundle);
                startActivity(intent);
            }
        }
    });
    // ListView每一个Item的长按事件
    convertView.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            if(isMultiSelect)
                return true;
            else
                isMultiSelect = true;

            for(int i = 0; i < parent.getChildCount(); i++){
                setCheckBoxIsVisible((parent.getChildAt(i).findViewById(R.id.diary_item_check)), true);
            }

            checkBox.setChecked(true);
            selectedPos.add(position);
            adapter.notifyDataSetChanged();
            
            return true;
        }
    });
    return convertView;
}
/**
 * 没有使用简单的setVisibility(int),而是权重来实现checkbox的隐藏和显示
 * 当然简单的View.VISIBLE和View.GONE也可以
 */
public void setCheckBoxIsVisible(CheckBox checkBox, boolean isVisible){
    if(isVisible){
        LinearLayout.LayoutParams weight = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1.0f);
        weight.setMarginEnd(36);
        checkBox.setLayoutParams(weight);
    }else {
        LinearLayout.LayoutParams weight = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 0.0f);
        weight.setMarginStart(Util.dp2px(Objects.requireNonNull(getContext()),16));
        checkBox.setLayoutParams(weight);
    }
}

3.拓展

全选:将所有的position存入selectedPos再调用adapter.notifyDataSetChanged()即可
删除:多选之后要注意位置的改变

猜你喜欢

转载自www.cnblogs.com/tamentaoyanwo/p/12218724.html