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

  MultiChoiceBaseAdapter是一个可以多选的BaseAdapter,使用的方式相比来说扩展性更强!

使用方式:

1.布局文件

2.写一个类继承MultiChoiceBaseAdapter

3.实现内部的各个方法

4.设置数据源和视图

5.完成保存的回调方法

一、布局文件

listview_actionmode_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/actionMode_listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </ListView>

</LinearLayout>

item.xml

注意:这里值得注意的是添加了一个CheckBox,它的id很重要。如果是:@android:id/checkbox的话,用户点击这个checkbox的时候直接会进入可以多选的状态,如果是用其他的id的话,点击它就是普通的选择,不会触发多选状态。

<?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> 

二、继承MultiChoiceBaseAdapter

构造函数中推荐传入的是一个list对象,一个是因为可以方便的动态删除或者增加元素,还有一个是方便扩展。比如有一个对象Person传入一个List<Person>对象,然后用get(……)方法就可以进行相应的设置了。如果传入的是数组对象,就很难动态删除和增加了。

    private class MultiBaseAdapter extends MultiChoiceBaseAdapter{

        private List<String> mData;
        
        /**
         * 构造函数
         * @param savedInstanceState
         */
        public MultiBaseAdapter(Bundle savedInstanceState,List<String> 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:删除选中的元素
                removeSelectedItems();
                return true;
            }
            return false;
        }
        
        /**
         * 删除已经选中的items 
         */
        private void removeSelectedItems() {
            // http://stackoverflow.com/a/4950905/244576
            List<Long> positions = new ArrayList<Long>(getCheckedItems());
            Collections.sort(positions, Collections.reverseOrder());
            for (long position : positions) {
                mData.remove((int)position);
            }
            finishActionMode();
        }

        @Override
        public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
            // TODO 自动生成的方法存根
            return false;
        }

        /**
         * 看适配器中有多少元素需要加载
         */
        @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;
                LayoutInflater inflater = LayoutInflater.from(getContext());
                convertView = inflater.inflate(layout, parent, false);
            }
            ViewGroup group = (ViewGroup)convertView;
            ((TextView)group.findViewById(R.id.item_textView)).setText(mData.get(position));
            ((CheckBox)group.findViewById(android.R.id.checkbox)).setVisibility(View.VISIBLE);
            return group;
        }
        
    }

三、设置适配器和保存的方法

    private ArrayList<String> items ;
    
    private MultiBaseAdapter adapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO 自动生成的方法存根
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listview_actionmode_layout);
        
        
        String[] data = {"android","ios","wp","c++",
                 "java","c#","javascript","vb",
                 "delphi","PB","ASP","SQL"};
        items = new  ArrayList<String>(Arrays.asList(data));
        
        ListView list = (ListView)findViewById(R.id.actionMode_listView);
        adapter = new MultiBaseAdapter(savedInstanceState, items);
        adapter.setAdapterView(list);
        adapter.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                    long arg3) {
                Toast.makeText(getApplicationContext(), "点击了"+items.get(position), 0).show();
            }
        });

    }
    
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        adapter.save(outState);
    }

大功告成!!!

下面是全部代码:

BaseAdapterTestActivity.java

package com.kale.multichoiceadaptertest;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.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.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.manuelpeinado.multichoiceadapter.normal.MultiChoiceBaseAdapter;

/**
 * 4.0上的用activity
 * 并且导入
 * import android.view.ActionMode;
 * import com.manuelpeinado.multichoiceadapter.normal.MultiChoiceBaseAdapter;
 * 兼容2.0导入ActionbarActivity
 * 并且导入
 * import android.support.v7.view.ActionMode;
 * import com.manuelpeinado.multichoiceadapter.compat.MultiChoiceBaseAdapter;
 */

/**
 * 
 * @author:Jack Tony
 * @tips  :
 * @date  :2014-10-21
 */
public class BaseAdapterTestActivity extends Activity{
    
    private ArrayList<String> items ;
    
    private MultiBaseAdapter adapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO 自动生成的方法存根
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listview_actionmode_layout);
        
        
        String[] data = {"android","ios","wp","c++",
                 "java","c#","javascript","vb",
                 "delphi","PB","ASP","SQL"};
        items = new  ArrayList<String>(Arrays.asList(data));
        
        ListView list = (ListView)findViewById(R.id.actionMode_listView);
        adapter = new MultiBaseAdapter(savedInstanceState, items);
        adapter.setAdapterView(list);
        adapter.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int position,
                    long arg3) {
                Toast.makeText(getApplicationContext(), "点击了"+items.get(position), 0).show();
            }
        });

    }
    
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        adapter.save(outState);
    }
    
    private class MultiBaseAdapter extends MultiChoiceBaseAdapter{

        private List<String> mData;
        
        /**
         * 构造函数
         * @param savedInstanceState
         */
        public MultiBaseAdapter(Bundle savedInstanceState,List<String> 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:删除选中的元素
                removeSelectedItems();
                return true;
            }
            return false;
        }
        
        /**
         * 删除已经选中的items 
         */
        private void removeSelectedItems() {
            // http://stackoverflow.com/a/4950905/244576
            List<Long> positions = new ArrayList<Long>(getCheckedItems());
            Collections.sort(positions, Collections.reverseOrder());
            for (long position : positions) {
                mData.remove((int)position);
            }
            finishActionMode();
        }

        @Override
        public boolean onPrepareActionMode(ActionMode arg0, Menu arg1) {
            // TODO 自动生成的方法存根
            return false;
        }

        /**
         * 看适配器中有多少元素需要加载
         */
        @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;
                LayoutInflater inflater = LayoutInflater.from(getContext());
                convertView = inflater.inflate(layout, parent, false);
            }
            ViewGroup group = (ViewGroup)convertView;
            ((TextView)group.findViewById(R.id.item_textView)).setText(mData.get(position));
            ((CheckBox)group.findViewById(android.R.id.checkbox)).setVisibility(View.VISIBLE);
            return group;
        }
        
    }

}

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

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

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

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

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

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

原文地址:https://www.cnblogs.com/tianzhijiexian/p/4041517.html