这篇其实没啥重要的,主要就算是个总结吧。

一、布局文件

这里实现的是类似于上图的多图选择的效果。关键在于item布局文件的写法。这也就是这个框架奇葩的一点,莫名其妙的要在一个自定义控件里面再放一个自定义的控件,如果不这样就出不了选中的效果。分析下原因是这里整个item被图片所覆盖了,仅仅设置一个有选择效果的父控件会被图片所覆盖,所以还得用一个可以选中的imageview进行替换imageview。

下面就是这个布局文件

item_gridview.xml

<?xml version="1.0" encoding="utf-8"?>
<com.manuelpeinado.multichoiceadapter.view.CheckableLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/custom_list_item_background"> <com.manuelpeinado.multichoiceadapter.view.CheckableImageView
android:id="@+id/item_imageView"
android:layout_width="match_parent"
android:layout_height="250dp"
android:scaleType="centerCrop" /> </com.manuelpeinado.multichoiceadapter.view.CheckableLinearLayout>

通过查看文档,我们可以知道这里的CheckableImageView 可以设置一个android:foreground属性来显示被选中的状态。类似于:

    <com.manuelpeinado.multichoiceadapter.view.CheckableImageView
android:id="@+id/item_imageView"
android:layout_width="match_parent"
android:layout_height="250dp"
android:scaleType="centerCrop"
android:foreground="@drawable/custom_list_item_background"/>

但这样就需要设置下选中状态的透明度,否则会完全遮挡住选中的图片内容了。

原文:https://github.com/ManuelPeinado/MultiChoiceAdapter/wiki/Gallery-tutorial

We cannot use an ImageView because the root of the item's layout must implement the Checkable interface. Luckily, the library includes a version of ImageView that does just that. An interesting thing about this class is that it doesn't use the android:background for its selector, since that would be obscured by the image. Instead, it draws the selector over the image, just like a ListView does in the drawSelectorOnTop mode. By default this selector is a semitransparent blue with opaque borders, as you can see in the screenshot above. You can customize it quite easily by defining your own selector in XML (don't forget the checked state) and assigning it to the android:foregroundattribute of your CheckableImageView element.

另一个布局文件:

gridview_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" > <GridView
android:id="@+id/gridLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCC"
android:horizontalSpacing="2dp"
android:numColumns="2"
android:stretchMode="columnWidth"
android:gravity="center"
android:verticalSpacing="2dp"
/> </LinearLayout>

二、改变actionMode标题文字的方法

在继承MultiChoiceBaseAdapter后可以实现getActionModeTitle()这个方法来设置自定义标题。这个方法名略让人迷茫,总之看源码就是每次item选中状态改变的时候会到这里来要一个String对象,用于设置标题。就和适配器中的getViewImpl()返回view差不多。

/**
* 系统在item选中状态被改变的时候会调用getActionModeTitle()来得到要显示的标题字样
* 这里得到被选中的items数目,可以用来改变actionmode上的标题字样。
* 下面想返回字符串就是标题了
*/
@Override
public String getActionModeTitle(int selected) {
return String.format("自定义标题:%d / %d", selected, getCount());
}

三、继承MultiChoiceBaseAdapter

    private class MultiBaseAdapter extends MultiChoiceBaseAdapter{

        private List<Integer> mData;

        /**
* 构造函数
* @param savedInstanceState
*/
public MultiBaseAdapter(Bundle savedInstanceState,List<Integer> data) {
super(savedInstanceState);
// TODO 自动生成的构造函数存根
mData = data;
} /**
* 创建ActionMode对象,必须返回true!!!
*/
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.my_action_mode, menu);
return true;
} /**
* item点击时处理的事件,从ActionMode.callback中继承过来的
*/
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.menu_share) {
Toast.makeText(getContext(), "分享了" + getCheckedItemCount() + "item", Toast.LENGTH_SHORT).show();
return true;
}
if (item.getItemId() == R.id.menu_discard) {
//TODO:删除选中的元素
return true;
}
return false;
} @Override
public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
// TODO 自动生成的方法存根
return false;
} /**
* 系统在item选中状态被改变的时候会调用getActionModeTitle()来得到要显示的标题字样
* 这里得到被选中的items数目,可以用来改变actionmode上的标题字样。
* 下面想返回字符串就是标题了
*/
@Override
public String getActionModeTitle(int selected) {
return String.format("自定义标题:%d / %d", selected, getCount());
} /**
* 看适配器中有多少元素需要加载
*/
@Override
public int getCount() {
// TODO 自动生成的方法存根
return mData.size();
} /**
* 通过position来得到相应的item,这里返回object对象
*/
@Override
public Object getItem(int position) {
// TODO 自动生成的方法存根
return mData.get(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_gridview;
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(layout, parent, false);
}
ViewGroup group = (ViewGroup)convertView;
((ImageView)group.findViewById(R.id.item_imageView)).setImageResource((mData.get(position)));
return group;
} }

四、配置适配器

如果不想要显示actionMode,只需要用adapter.showActionMode(false);来屏蔽掉它。这就是我扩展的比较好的一点,既不改变原来的使用方法,又可以自由扩展。

    MultiBaseAdapter adapter;

    @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO 自动生成的方法存根
super.onCreate(savedInstanceState);
setContentView(R.layout.gridview_layout); Integer[] pics = {R.drawable.aig,R.drawable.bank_of_america,R.drawable.chrysler,
R.drawable.empire_state,R.drawable.nyt,R.drawable.one_wtc}; List<Integer> items = new ArrayList<>(Arrays.asList(pics)); GridView gridView = (GridView)findViewById(R.id.gridLayout); adapter = new MultiBaseAdapter(savedInstanceState, items);
adapter.setAdapterView(gridView);
//adapter.showActionMode(false);//开启后变成普通模式,就不需要实现actionmode了
adapter.setOnSelectedStateChangeListener(new OnSelectedStateChangeListener() { @Override
public void onSelectedStateChanged(int checkedItemCount) {
// TODO 自动生成的方法存根
Toast.makeText(getApplicationContext(), "选中了"+checkedItemCount+"个", 0).show();
}
}); }

全部搞定~~~

全部代码:

package com.kale.multichoiceadaptertest;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast; import com.manuelpeinado.multichoiceadapter.base.OnSelectedStateChangeListener;
import com.manuelpeinado.multichoiceadapter.compat.MultiChoiceBaseAdapter; public class GridViewTestActvity extends ActionBarActivity{ MultiBaseAdapter adapter; @Override
protected void onCreate(Bundle savedInstanceState) {
// TODO 自动生成的方法存根
super.onCreate(savedInstanceState);
setContentView(R.layout.gridview_layout); Integer[] pics = {R.drawable.aig,R.drawable.bank_of_america,R.drawable.chrysler,
R.drawable.empire_state,R.drawable.nyt,R.drawable.one_wtc}; List<Integer> items = new ArrayList<>(Arrays.asList(pics)); GridView gridView = (GridView)findViewById(R.id.gridLayout); adapter = new MultiBaseAdapter(savedInstanceState, items);
adapter.setAdapterView(gridView);
//adapter.showActionMode(false);//开启后变成普通模式,就不需要实现actionmode了
adapter.setOnSelectedStateChangeListener(new OnSelectedStateChangeListener() { @Override
public void onSelectedStateChanged(int checkedItemCount) {
// TODO 自动生成的方法存根
Toast.makeText(getApplicationContext(), "选中了"+checkedItemCount+"个", 0).show();
}
}); } @Override
protected void onSaveInstanceState(Bundle outState) {
adapter.save(outState);
} private class MultiBaseAdapter extends MultiChoiceBaseAdapter{ private List<Integer> mData; /**
* 构造函数
* @param savedInstanceState
*/
public MultiBaseAdapter(Bundle savedInstanceState,List<Integer> data) {
super(savedInstanceState);
// TODO 自动生成的构造函数存根
mData = data;
} /**
* 创建ActionMode对象,必须返回true!!!
*/
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.my_action_mode, menu);
return true;
} /**
* item点击时处理的事件,从ActionMode.callback中继承过来的
*/
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == R.id.menu_share) {
Toast.makeText(getContext(), "分享了" + getCheckedItemCount() + "item", Toast.LENGTH_SHORT).show();
return true;
}
if (item.getItemId() == R.id.menu_discard) {
//TODO:删除选中的元素
return true;
}
return false;
} @Override
public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
// TODO 自动生成的方法存根
return false;
} /**
* 系统在item选中状态被改变的时候会调用getActionModeTitle()来得到要显示的标题字样
* 这里得到被选中的items数目,可以用来改变actionmode上的标题字样。
* 下面想返回字符串就是标题了
*/
@Override
public String getActionModeTitle(int selected) {
return String.format("自定义标题:%d / %d", selected, getCount());
} /**
* 看适配器中有多少元素需要加载
*/
@Override
public int getCount() {
// TODO 自动生成的方法存根
return mData.size();
} /**
* 通过position来得到相应的item,这里返回object对象
*/
@Override
public Object getItem(int position) {
// TODO 自动生成的方法存根
return mData.get(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_gridview;
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(layout, parent, false);
}
ViewGroup group = (ViewGroup)convertView;
((ImageView)group.findViewById(R.id.item_imageView)).setImageResource((mData.get(position)));
return group;
} }
}

源码下载:http://download.csdn.net/detail/shark0017/8065691

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

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

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

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

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

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

开源项目MultiChoiceAdapter详解(六)——GridView和MultiChoiceBaseAdapter配合使用的更多相关文章

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

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

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

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

  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. .NetCore Linux中安装Grafana界面及配置InfluxDB相关设置

    前面的文章已经安装好了InfluxDB 安装 wget https://s3-us-west-2.amazonaws.com/grafana-releases/release/grafana-5.1. ...

  2. 014 再次整理关于hadoop中yarn的原理及运行

    一:对yarn的理解 1.关于yarn的组成 大约分成主要的四个. Resourcemanager,Nodemanager,Applicationmaster,container 2.Resource ...

  3. 探索Java的日志世界

    探索Java的日志世界 本文的思维导图 一.主题 打开日志的大门,探索的Java日志世界 二.目标 了解常用的日志框架 掌握日志框架的选择和使用以及开发规范 了解日志框架中的一些设计思想 三.内容 1 ...

  4. C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例

    C#开发Unity游戏教程循环遍历做出判断及Unity游戏示例 Unity中循环遍历每个数据,并做出判断 很多时候,游戏在玩家做出判断以后,游戏程序会遍历玩家身上大量的所需数据,然后做出判断,即首先判 ...

  5. Codeforces Round #505 (Div 1 + Div 2) (A~D)

    目录 Codeforces 1025 A.Doggo Recoloring B.Weakened Common Divisor C.Plasticine zebra D.Recovering BST( ...

  6. Stf-windows版本

    Stf-windows Stf 原项目地址:https://github.com/openstf/stf . 介绍 用于Web端设备远程管理 系统支持 支持Android版本2.3.3 (SDK10) ...

  7. Docker系列之(一):10分钟玩转Docker

    1.前言 进入云计算的时代,各大云提供商AWS,阿里云纷纷推出针对Docker的服务,现在Docker是十分火爆,那么Docker到底是什麽,让我们来体验一下. 2.Docker是什麽 Docker是 ...

  8. 2015 年度新增开源软件排名 TOP 100 - 开源中国社区

    2015 年度新增开源软件排名 TOP 100 - 开源中国社区 39.ABTestingGateway http://www.oschina.net/news/69808/2015-annual-r ...

  9. 从PHP客户端看MongoDB通信协议(转)

    MongoDB 的 PHP 客户端有一个 MongoCursor 类,它是用于获取一次查询结果集的句柄(或者叫游标),这个简单的取数据操作,内部实现其实不是那么简单.本文就通过对 MongoCurso ...

  10. web压力测试工具(小而精)

    实际的测试过程中,我们一般都是采用A.B两台机器,一台跑Web服务,另外一台跑ab测试.也有的情况是单机对单机可能测不出结果,那就要采用很多台机器同是跑AB去请求一台机器进行测试,根据多台机器反馈的结 ...