上次写到了开源项目MultiChoiceAdapter详解(四)——MultiChoiceBaseAdapter的使用,其实我们仍旧可以不使用ActionMode的,所以这里就写一个自己扩展的方法。

一、布局文件

listview_normal_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <ListView
android:id="@+id/normal_listView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" >
</ListView> <LinearLayout
android:id="@+id/setting_linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"> <Button
android:id="@+id/selectAll_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全选"
android:layout_weight="1"
android:onClick="buttonListener"/> <Button
android:id="@+id/cancle_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消"
android:layout_weight="1"
android:onClick="buttonListener"/> <Button
android:id="@+id/delete_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="删除"
android:onClick="buttonListener"/> <Button
android:id="@+id/share_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="分享"
android:layout_weight="1"
android:onClick="buttonListener"/> </LinearLayout> </LinearLayout>

item.xml

<?xml version="1.0" encoding="utf-8"?>
<com.manuelpeinado.multichoiceadapter.view.CheckableLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" android:background="@drawable/custom_list_item_background" android:orientation="horizontal">
<!-- 上面必须要用自定义的layout,否则不会有选中的效果!!! --> <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:orientation="horizontal" > <TextView
android:id="@+id/item_textView"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_gravity="center_vertical"
android:textColor="#000000"
android:layout_weight="1"
android:textAppearance="?android:attr/textAppearanceLarge" /> <!--
CheckBox中一定要写上focusable="false"否则无法相应点击事件
@android:id/checkbox这个也一定要写,如果不写的话点击checkbox就不会触发多选状态
如果你不想要选中checkbox就触发多选状态的话,这里可以用自己定义的id就行
-->
<CheckBox
android:id="@android:id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:layout_weight="1"
android:layout_marginLeft="40dp"
android:textColor="#000000"
android:focusable="false"
android:visibility="gone"
android:text="" /> </LinearLayout>
</com.manuelpeinado.multichoiceadapter.view.CheckableLinearLayout>

view_header.xml

这个是用于给listview添加一个头部视图的,顺带学习下listview添加顶部视图的方法呗~

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="16dp"
android:paddingTop="16dp"
android:text="这是给listview添加的顶部视图"
android:gravity="center_horizontal"
android:textStyle="bold" />

二、继承类然后实现

可以看见这里关于ActionMode有关的回调方法我都是空实现

    private class MultiBaseAdapter extends MultiChoiceBaseAdapter{

        private String[] mData;

        /**
* 构造函数
* @param savedInstanceState
*/
public MultiBaseAdapter(Bundle savedInstanceState,String[] data) {
super(savedInstanceState);
// TODO 自动生成的构造函数存根
mData = data;
} @Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return true;
} @Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
} @Override
public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
// TODO 自动生成的方法存根
return false;
} /**
* 看适配器中有多少元素需要加载
*/
@Override
public int getCount() {
// TODO 自动生成的方法存根
return mData.length;
} /**
* 通过position来得到相应的item,这里返回object对象
*/
@Override
public Object getItem(int position) {
// TODO 自动生成的方法存根
return mData[position];
} /**
* 通过position得到id
*/
@Override
public long getItemId(int position) {
// TODO 自动生成的方法存根
return position;
} /**
* 返回item的view对象
*/
@Override
protected View getViewImpl(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
int layout = R.layout.item;
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(layout, parent, false);
}
ViewGroup group = (ViewGroup)convertView;
((TextView)group.findViewById(R.id.item_textView)).setText(mData[position]);
((CheckBox)group.findViewById(android.R.id.checkbox)).setVisibility(View.VISIBLE);
return group;
} }

三、配置适配器和相应的监听器

listView.addHeaderView(createHeaderView(), null, false);是给listview添加头视图的方法,传入false表示头图不能点击

    private MultiBaseAdapter adapter;

    @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO 自动生成的方法存根
super.onCreate(savedInstanceState);
setContentView(R.layout.listview_normal_layout); String[] data = {"android","ios","wp","c++",
"java","c#","javascript","vb",
"delphi","PB","ASP","SQL"}; final LinearLayout settingLL = (LinearLayout)findViewById(R.id.setting_linearLayout);
settingLL.setVisibility(View.GONE); ListView listView = (ListView)findViewById(R.id.normal_listView); /**
* 给listview顶部添加2个额外视图,设置顶部视图不可点击
*/
listView.addHeaderView(createHeaderView(), null, false);
listView.addHeaderView(createHeaderView(), null, false);
//实例化适配器
adapter = new MultiBaseAdapter(savedInstanceState, data);
//添加视图
adapter.setAdapterView(listView);
//设置不显示actionMode
adapter.showActionMode(false);
//点击事件
adapter.setOnItemClickListener(new MyItemClick(adapter));
//监听选中的状态
adapter.setOnSelectedStateChangeListener(new OnSelectedStateChangeListener() {
/**
* checkedItemCount = 已经选中的item数目
*/
@Override
public void onSelectedStateChanged(int checkedItemCount) {
if (checkedItemCount != 0) {
settingLL.setVisibility(View.VISIBLE);
}
else {
settingLL.setVisibility(View.GONE);
}
}
});
}
    private View createHeaderView() {
return LayoutInflater.from(this).inflate(R.layout.view_header, null);
}

点击事件的监听器:

    /**
* @author:Jack Tony
* @tips :点击事件的监听器
* @date :2014-10-20
*/
private class MyItemClick implements OnItemClickListener{ private MultiChoiceBaseAdapter mAdapter; public MyItemClick(MultiChoiceBaseAdapter adapter) {
mAdapter = adapter;
} @Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
//因为在顶部添加了2个视图,所以这里的位置要下移两位 Toast.makeText(getApplicationContext(), "点击了: " + mAdapter.getItem(position - 2), Toast.LENGTH_SHORT).show();
} }

四、用回调方法来优化

    @Override
protected void onSaveInstanceState(Bundle outState) {
adapter.save(outState);
} @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK ) {
if (adapter.getCheckedItemCount() > 0) {
cancleAll(adapter);
return true;
}
}
return super.onKeyDown(keyCode, event);
}
    public void buttonListener(View v) {
switch (v.getId()) {
case R.id.selectAll_button:
selectAll(adapter);
break;
case R.id.cancle_button:
cancleAll(adapter);
break;
case R.id.delete_button:
delectItems(adapter);
break;
case R.id.share_button:
Toast.makeText(getApplicationContext(), "分享"+Arrays.toString(getSelectedItems(adapter)), 1).show();
cancleAll(adapter);
break;
default:
break;
}
} /**
* 全选
* @param adapter
*/
private void selectAll(MultiChoiceBaseAdapter adapter) {
for (int i = 0; i < adapter.getCount(); ++i) {
adapter.setItemChecked(i, true);
}
} /**
* 取消所有选择效果
* @param adapter
*/
private void cancleAll(MultiChoiceBaseAdapter adapter) {
for (int i = 0; i < adapter.getCount(); ++i) {
adapter.setItemChecked(i, false);
}
} /**
* 得到已经选中的items
* @param adapter
* @return
*/
private String[] getSelectedItems(MultiChoiceBaseAdapter adapter) {
//得到选中的items
Set<Long> selection = adapter.getCheckedItems();
String[] items = new String[selection.size()];
int i = 0;
for (long position : selection) {
items[i++] = (String)adapter.getItem((int)position);
}
return items;
} /**
* 删除已经选中的items
* @param adapter
*/
private void delectItems(MultiChoiceBaseAdapter adapter) {
//通过判断名字来remove掉这些items
// TODO:删除某些元素,因为这里的数据源是String[]所以没有链表那样好删除,就没去实现。
//实际中:推荐用链表来动态删除元素,在删除时需要注意的是最好以唯一的id,如position来进行删除
cancleAll(adapter);
}

搞定了!!!

全部代码:

package com.kale.multichoiceadaptertest;

import java.util.Arrays;
import java.util.Set; import android.app.Activity;
import android.os.Bundle;
import android.support.v7.view.ActionMode;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast; import com.manuelpeinado.multichoiceadapter.base.OnSelectedStateChangeListener;
import com.manuelpeinado.multichoiceadapter.compat.MultiChoiceBaseAdapter; public class BaseAdapterNormalTestActivity extends Activity{ private MultiBaseAdapter adapter; @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO 自动生成的方法存根
super.onCreate(savedInstanceState);
setContentView(R.layout.listview_normal_layout); String[] data = {"android","ios","wp","c++",
"java","c#","javascript","vb",
"delphi","PB","ASP","SQL"}; final LinearLayout settingLL = (LinearLayout)findViewById(R.id.setting_linearLayout);
settingLL.setVisibility(View.GONE); ListView listView = (ListView)findViewById(R.id.normal_listView); /**
* 给listview顶部添加2个额外视图,设置顶部视图不可点击
*/
listView.addHeaderView(createHeaderView(), null, false);
listView.addHeaderView(createHeaderView(), null, false);
//实例化适配器
adapter = new MultiBaseAdapter(savedInstanceState, data);
//添加视图
adapter.setAdapterView(listView);
//设置不显示actionMode
adapter.showActionMode(false);
//点击事件
adapter.setOnItemClickListener(new MyItemClick(adapter));
//监听选中的状态
adapter.setOnSelectedStateChangeListener(new OnSelectedStateChangeListener() {
/**
* checkedItemCount = 已经选中的item数目
*/
@Override
public void onSelectedStateChanged(int checkedItemCount) {
if (checkedItemCount != 0) {
settingLL.setVisibility(View.VISIBLE);
}
else {
settingLL.setVisibility(View.GONE);
}
}
});
} @Override
protected void onSaveInstanceState(Bundle outState) {
adapter.save(outState);
} @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK ) {
if (adapter.getCheckedItemCount() > 0) {
cancleAll(adapter);
return true;
}
}
return super.onKeyDown(keyCode, event);
} private View createHeaderView() {
return LayoutInflater.from(this).inflate(R.layout.view_header, null);
} private class MultiBaseAdapter extends MultiChoiceBaseAdapter{ private String[] mData; /**
* 构造函数
* @param savedInstanceState
*/
public MultiBaseAdapter(Bundle savedInstanceState,String[] data) {
super(savedInstanceState);
// TODO 自动生成的构造函数存根
mData = data;
} @Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return true;
} @Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return false;
} @Override
public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
// TODO 自动生成的方法存根
return false;
} /**
* 看适配器中有多少元素需要加载
*/
@Override
public int getCount() {
// TODO 自动生成的方法存根
return mData.length;
} /**
* 通过position来得到相应的item,这里返回object对象
*/
@Override
public Object getItem(int position) {
// TODO 自动生成的方法存根
return mData[position];
} /**
* 通过position得到id
*/
@Override
public long getItemId(int position) {
// TODO 自动生成的方法存根
return position;
} /**
* 返回item的view对象
*/
@Override
protected View getViewImpl(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
int layout = R.layout.item;
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(layout, parent, false);
}
ViewGroup group = (ViewGroup)convertView;
((TextView)group.findViewById(R.id.item_textView)).setText(mData[position]);
((CheckBox)group.findViewById(android.R.id.checkbox)).setVisibility(View.VISIBLE);
return group;
} } public void buttonListener(View v) {
switch (v.getId()) {
case R.id.selectAll_button:
selectAll(adapter);
break;
case R.id.cancle_button:
cancleAll(adapter);
break;
case R.id.delete_button:
delectItems(adapter);
break;
case R.id.share_button:
Toast.makeText(getApplicationContext(), "分享"+Arrays.toString(getSelectedItems(adapter)), 1).show();
cancleAll(adapter);
break;
default:
break;
}
} /**
* 全选
* @param adapter
*/
private void selectAll(MultiChoiceBaseAdapter adapter) {
for (int i = 0; i < adapter.getCount(); ++i) {
adapter.setItemChecked(i, true);
}
} /**
* 取消所有选择效果
* @param adapter
*/
private void cancleAll(MultiChoiceBaseAdapter adapter) {
for (int i = 0; i < adapter.getCount(); ++i) {
adapter.setItemChecked(i, false);
}
} /**
* 得到已经选中的items
* @param adapter
* @return
*/
private String[] getSelectedItems(MultiChoiceBaseAdapter adapter) {
//得到选中的items
Set<Long> selection = adapter.getCheckedItems();
String[] items = new String[selection.size()];
int i = 0;
for (long position : selection) {
items[i++] = (String)adapter.getItem((int)position);
}
return items;
} /**
* 删除已经选中的items
* @param adapter
*/
private void delectItems(MultiChoiceBaseAdapter adapter) {
//通过判断名字来remove掉这些items
// TODO:删除某些元素,因为这里的数据源是String[]所以没有链表那样好删除,就没去实现。
//实际中:推荐用链表来动态删除元素,在删除时需要注意的是最好以唯一的id,如position来进行删除
cancleAll(adapter);
} /**
* @author:Jack Tony
* @tips :点击事件的监听器
* @date :2014-10-20
*/
private class MyItemClick implements OnItemClickListener{ private MultiChoiceBaseAdapter mAdapter; public MyItemClick(MultiChoiceBaseAdapter adapter) {
mAdapter = adapter;
} @Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
//因为在顶部添加了2个视图,所以这里的位置要下移两位 Toast.makeText(getApplicationContext(), "点击了: " + mAdapter.getItem(position - 2), Toast.LENGTH_SHORT).show();
} }
}

开源项目MultiChoiceAdapter详解(一)——概要介绍

开源项目MultiChoiceAdapter详解(二)——MultiChoiceArrayAdapter的使用

开源项目MultiChoiceAdapter详解(三)——MulitChoiceNormalArrayAdapter的使用

开源项目MultiChoiceAdapter详解(四)——MultiChoiceBaseAdapter的使用

开源项目MultiChoiceAdapter详解(五)——可扩展的MultiChoiceBaseAdapter

开源项目MultiChoiceAdapter详解(六)——GridView和MultiChoiceBaseAdapter配合使用

开源项目MultiChoiceAdapter详解(五)——可扩展的MultiChoiceBaseAdapter的更多相关文章

  1. 开源项目MultiChoiceAdapter详解(六)——GridView和MultiChoiceBaseAdapter配合使用

    这篇其实没啥重要的,主要就算是个总结吧. 一.布局文件 这里实现的是类似于上图的多图选择的效果.关键在于item布局文件的写法.这也就是这个框架奇葩的一点,莫名其妙的要在一个自定义控件里面再放一个自定 ...

  2. 开源项目MultiChoiceAdapter详解(四)——MultiChoiceBaseAdapter的使用

    MultiChoiceBaseAdapter是一个可以多选的BaseAdapter,使用的方式相比来说扩展性更强! 使用方式: 1.布局文件 2.写一个类继承MultiChoiceBaseAdapte ...

  3. 开源项目MultiChoiceAdapter详解(三)——MulitChoiceNormalArrayAdapter的使用

    MulitChoiceNormalArrayAdapter是我自己定义的一个类,其实就是实现了MulitChoiceArrayAdapter,为什么做这个简单的实现类呢,因为这样我们在不用Action ...

  4. 开源项目MultiChoiceAdapter详解(二)——MultiChoiceArrayAdapter的使用

    MultiChoiceArrayAdapter其实就是可以多选的ArrayAdapter了,ArrayAdpter我们已经很熟悉了.MultiChoiceArrayAdapter这个类是抽象类,所以使 ...

  5. 开源项目MultiChoiceAdapter详解(一)——概要介绍

    项目地址:https://github.com/ManuelPeinado/MultiChoiceAdapter 这个项目主要是提供了一个多选适配器,使用者可以用它来替换传统的适配器,用途还算比较广泛 ...

  6. 开源项目PullToRefresh详解(二)——PullToRefreshGridView

    这里介绍的是PullToRefreshGridView的使用方法,和之前的PullToRefreshListView方法如出一辙,因为这个开源项目模块化很棒,所以很容易实现.等于说我们可以按照之前使用 ...

  7. 开源项目PullToRefresh详解(一)——PullToRefreshListView

       开源项地址:https://github.com/chrisbanes/Android-PullToRefresh 下拉刷新这个功能我们都比较常见了,今天介绍的就是这个功能的实现.我将按照这个开 ...

  8. 开源项目PullToRefresh详解(四)——PullToRefreshListView和ViewPager的结合使用

    其实这个不是什么新东西了,在介绍(一)中我们就知道了PullToRefreshListView的用法,这里只要将其放入到ViewPager中就行啦.ViewPager还是和以往一样的定义和使用,在适配 ...

  9. Android 开源项目DiskLruCache 详解

    有兴趣的同学可以读完这篇文章以后 可以看看这个硬盘缓存和volley 或者是其他 图片缓存框架中使用的硬盘缓存有什么异同点. 讲道理的话,其实硬盘缓存这个模块并不难写,难就难在 你要考虑到百分之0.1 ...

随机推荐

  1. 029 RDD Join相关API,以及程序

    1.数据集 A表数据: 1 a 2 b 3 c B表数据: 1 aa1 1 aa2 2 bb1 2 bb2 2 bb3 4 dd1 2.join的分类 inner join left outer jo ...

  2. Java之路(四)数组初始化

    本文主要讲数组的初始化方法.可变参数列表以及可变参数列表对函数重载的影响. 1.数组初始化 定义数组的方式: int[] arr1; 或  int arr1[]; 数组初始化 通过上边的定义,我们只是 ...

  3. [C编码笔记] 空串与NULL是不一样的

    int main() { char *str = NULL; printf("%p \n", str); printf("%p \n", &str); ...

  4. 应用Mongoose开发MongoDB(2)模型(models)

    数据模型及基础操作模板 为了使工程结构清晰,将数据模型(Schema, Model)的建立与增删查改的基础操作模板写在一起,命名为数据库设计中的Collection(对应于关系型数据库中的表定义)名, ...

  5. jQuery选择器(转)

    原文:http://www.cnblogs.com/qinwang913/p/3444135.html 一.基本分类 jQuery选择器大致可以分为两类,基本选择器和过滤选择器,总体结构体系如下:   ...

  6. 高能天气——团队Scrum冲刺阶段-Day 7 总结

    高能天气--团队Scrum冲刺阶段-Day 7 总结 今日完成任务 于欣月:修改项目说明书,帮助修改应用 余坤澎:进行应用整合的收尾工作 康皓越:进行应用整合的收尾工作 范雯琪:修改项目说明书,完成项 ...

  7. 大数据小视角4:小议Lambda 与 Kappa 架构,不可变数据的计算探索

    这个系列文章之前因为私事荒废了很久,继续更新--之前与老大谈论架构时,老大和我聊了聊分布式数据处理之中的Lambda结构,之前在<Designing Data-Intensive Applica ...

  8. linux学习笔记-2.常用命令

    说明:安装linux时,创建一个luao用户,然后使用root用户登陆系统 1.进入到用户根目录 cd ~ 或 cd cd / 返回到根目录 2.查看当前所在目录 pwd 3.进入到luao用户根目录 ...

  9. 苹果Mac OS 显示隐藏文件

    苹果Mac OS 操作系统下,隐藏文件默认为隐藏状态,隐藏文件是否显示有多种方法可以设置. 方法一: 打开终端,输入命令行 显示Mac隐藏文件的命令: defaults write com.apple ...

  10. Android - Base64

    Android 将图片转换为Base64 public void convertToBase64(View view) throws IOException { //获取ImageView的图片 Bi ...