ListView多选操作模式详解CHOICE_MODE_MULTIPLE与CHOICE_MODE_MULTIPLE_MODAL

本文详细介绍了如何实现ListView的多选操作,包括使用CHOICE_MODE_MULTIPLE和CHOICE_MODE_MULTIPLE_MODAL的区别及应用场景。通过示例代码展示了如何设置和使用这两种模式,指出常见错误,并提供了多选操作的实战代码,帮助开发者更好地理解和运用ListView的多选功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇文章我们将详细的介绍如何实现ListView的多选操作,文中将会纠正在使用ListViewCHOICE_MODE_MULTIPLE或者CHOICE_MODE_MULTIPLE_MODAL时容易犯的错误,以及

CHOICE_MODE_MULTIPLE与CHOICE_MODE_MULTIPLE_MODAL的区别。最后我们将给出一个demo来演示两种多选操作的实现。


一、在不使用ListView多选模式的情况下

注:我认为这一节可以不看,因为我觉得不使用ListView的多选模式有点愚蠢。

如果我们不知道ListView自带多选模式,那么我们一般是通过维护一个保存被选择position集合来实现多选的,通常情况下这个集合类型我们选择HashSet。

实现的大致框架如下:

Adapter中:

保存被选择的position


1
public HashSet<Long> selectedItems = new HashSet<Long>();


getView中判断当前Position是否在集合中,从而显示不同的外观


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
     public View getView(int position, View convertView, ViewGroup par) {
......
             if (selectedItems.contains((long)position)){
                 holder.cBox.setChecked( true );
             } else {
                 holder.cBox.setChecked( false );
             }
             if (selectedMode==AppContext.MULTI_SELECTED){
                 holder.cBox.setVisibility(View.VISIBLE);
                 holder.check_box_wraper.setVisibility(View.VISIBLE);
             } else {
                 holder.cBox.setVisibility(View.GONE);
                 holder.check_box_wraper.setVisibility(View.GONE);
             }
.....

Activity中:

主要是处理onItemClick事件,在不同模式下,做不同的处理。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
     //普通模式 :直接打开一个activity
         if (itemClickActionMode==AppContext.VIEW_NOTE){
             Long mId=Long.parseLong(idText.getText().toString());
             Uri uri = ContentUris.withAppendedId(getIntent().getData(), mId);
             startActivity( new Intent(Intent.ACTION_VIEW, uri));
         }
         //多选模式:更新adapter中selectedItems 集合的值,同时 让adapter在getView中改变item的外观。
        else {
             ViewHolder vHollder = (ViewHolder) v.getTag();
             if (mAdapter.selectedItems.contains((long)position)){
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
                 mAdapter.selectedItems.remove((long)position);
             } else {
                         mAdapter.selectedItems.add((long)position);
             }
             mAdapter.notifyDataSetChanged();
             onItemSelected(getSelectedCount());    
         }
     }


上面的做法其实用的很普遍。但是我们不提倡。


二、使用ListViiewCHOICE_MODE_MULTIPLE模式


ListView有四种模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
  * Normal list that does not indicate choices
  */
public static final int CHOICE_MODE_NONE = 0;
/**
  * The list allows up to one choice
  */
public static final int CHOICE_MODE_SINGLE = 1;
/**
  * The list allows multiple choices
  */
public static final int CHOICE_MODE_MULTIPLE = 2;
/**
  * The list allows multiple choices in a modal selection mode
  */
public static final int CHOICE_MODE_MULTIPLE_MODAL = 3;


其中CHOICE_MODE_NONE是普通模式,CHOICE_MODE_SINGLE是单选模式,不常用,CHOICE_MODE_MULTIPLECHOICE_MODE_MULTIPLE_MODAL都是多选模式,他们的区别稍后我们会讲到。

所以ListView在设计的时候其实是考虑了多选操作的,我们没有必要自己再像第一节描述的那样专门维护一个HashSet来保存被选择的position。实现ListView的多选操作的代码在ListView直接父类AbsListView中,AbsListView已经有一个mCheckStates变量来做了保存被选择的position这个事情。mCheckStates的定义如下:


1
SparseBooleanArray mCheckStates;

AbsListView还定义了如下公共方法:

//判断一个item是否被选中

1
public boolean isItemChecked(int position);

//获得被选中item的总数

1
public int getCheckedItemCount();

//选中一个item

1
public void setItemChecked(int position, boolean value);

//清除选中的item

1
public void clearChoices();


当点击一个item的时候absListView中会调用performItemClick,如果是CHOICE_MODE_MULTIPLE,则该item点击一次,mCheckStates中相应位置的状态变更一次。然后我们就可以通过listView的getCheckedItemCount()方法获取选择了多少个;isItemChecked(int position)方法判断一个item是不是被选中。

有了这些原生sdk的支持,难道还有什么多选操作是不能实现的吗?所以是不是应该考虑放弃第一节中描述的那种方法了呢?遗憾的是很多android开发者即使是用了CHOICE_MODE_MULTIPLE,仍然没有去利用这些ListView自带的功能,估计是根本不知道该CHOICE_MODE_MULTIPLE的 特性吧,这其实也是android程序员与ios程序员真正存在差距的地方。


CHOICE_MODE_MULTIPLE实战


先看看效果图


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值