最简洁代码实现Listview多选

记得刚开始学android开发时要实现Listview多选然后批量操作的时候,用Checkbox+Textview,因为adapter复用后上下翻页的时候Checkbox状态无法保存,然后用一个全局变量记住该状态,翻页的时候再恢复状态。现在想想这么搞不仅low爆了,而且效率低。由于最近项目又需要实现类似的功能,想想不能重蹈覆辙,于是谷歌了一把,看到CheckedTextView,原来谷歌工程师已经帮我们实现了类似的功能。本来以为很简单,随便两下就搞定,等到自己动手,才发现不是那么回事,于是写下此文记录下来。

先来看完整的过程:
1.添加控件

<ListView
    android:id="@+id/lvMain"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:choiceMode="multipleChoice" />

2.设置数据

for (int i=0;i<100;i++)
        {     mDataList.add("item--"+i);     }
MyBaseAdapterListviewadapter=new MyBaseAdapterListview(this,mDataList,android.R.layout.simple_list_item_multiple_choice,true) {
    @Override
    public void convert(MyViewHolderExpandbleListView holder, String s, int position) {
         CheckedTextView  checkedTextView = holder.getView(android.R.id.text1);
        checkedTextView.setText(s);
    }
};

上面MyBaseAdapterListview是我自己封装的一个Adapter类,用来填充Listview数据,是不是简单易用?工具包含三个类,Demo里面有,可以直接拿来用。也可以从github引用,地址为https://github.com/crook3/ExpandableListviewAdapter
3.监听点击事件

lvMain.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView parent, View view, int position, long id) {
        sparseBooleanArray=lvMain.getCheckedItemPositions();
        int size=sparseBooleanArray.size();
        String result = "";
        for (int i=0;iif (sparseBooleanArray.valueAt(i))result+=sparseBooleanArray.keyAt(i)+"*";
        }
        Toast.makeText(MainActivity.this,result,Toast.LENGTH_LONG).show();
    }
});

运行结果:
最简洁代码实现Listview多选_第1张图片

OK,完美!
使用系统提供的布局方便简单,不用自己管理Checkbox的状态了,多么美好啊。但是有时候并不能满足我们的需求,比如说需要添加一张图片。这个时候就需要自定义了Listview的item的布局了,好,那直接来一个LinearLayout,里面包Imageview和 CheckedTextView,不就可以了吗。恩,你还是太年轻了,如果这么搞你会发现chechbox的状态无法像之前进行自我管理了,这应该是因为CheckedTextView
不再是根布局导致系统无法管理。所以最后,为了保证CheckedTextView就是根布局,我们只能如下布局activity_main_item:

<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tv1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:checkMark="?android:attr/listChoiceIndicatorMultiple"
    android:drawableLeft="@mipmap/ic_launcher"
    />

然后添加数据源的时候采用在一个Textview里面进行换行的思想来实现多行的效果,这样以最少的代码基本满足我们的需求了。

mDataList.add("item--"+i+" \n test1 \n test2");
MyBaseAdapterListviewadapter=new MyBaseAdapterListview(this,mDataList,R.layout.activity_main_item,true) {
            @Override
            public void convert(MyViewHolderExpandbleListView holder, String s, int position) {
                 CheckedTextView  checkedTextView = holder.getView(R.id.tv1);
                checkedTextView.setText(s);
           }
       };

自定义布局运行界面
最简洁代码实现Listview多选_第2张图片

自定义复选框颜色及左右,

android:checkMarkTint="@android:color/holo_green_dark"
    android:checkMark="?android:attr/listChoiceIndicatorMultiple"
    android:drawableTint="@android:color/holo_blue_bright"
    android:drawableLeft="?android:attr/listChoiceIndicatorMultiple"

运行结果

最简洁代码实现Listview多选_第3张图片

如果想子item文本之间间隔更大,使用android:lineSpacingExtra="10dp"

最简洁代码实现Listview多选_第4张图片

至此,整个过程结束,相信大家使用起来没什么问题了。

有两点需要说明
1、从 class CheckedTextView extends TextView implements Checkable看出CheckedTextView 兼具Textview和CheckBox特性。
2、lvMain.getCheckedItemPositions()的返回值用SparseBooleanArray数组接收,要知道通过键值对的方式去取值sparseBooleanArray.valueAt(i)和sparseBooleanArray.keyAt(i)。

源码下载地址

你可能感兴趣的:(安卓开发入门系列)