zoukankan      html  css  js  c++  java
  • 开源项目MultiChoiceAdapter详解(一)——概要介绍

    项目地址:https://github.com/ManuelPeinado/MultiChoiceAdapter

    这个项目主要是提供了一个多选适配器,使用者可以用它来替换传统的适配器,用途还算比较广泛。但是,但是……这个开源项目写的真的挺不好的,它大量使用了ActionMode,基本都是讲ActionMode和Adapter写到一起了,扩展性十分的低。而且这里面还有各种各样的小细节需要注意的,比如返回值啦,或者是控件的定义方式,是否要用自定义控件什么的了。在官方文档的介绍中说各种简单和实用,其实真正用下来发现学它比学其他的框架要难三倍以上,原版的项目很不推荐使用。所以这里我自己讲这个开源项目进行了改进,即确保不变动原来的使用方式,又增加了扩展性,所以极力推荐用我改写的项目来实现!本篇先进行简要的介绍下原有的功能,和我添加的功能。

    一、自定义控件

    我把自定义控件用包名进行了分割,大家可以明显的看出这个项目自定义了这几个控件。这些控件主要是作为adapter中item视图来用的。一般我们的item.xml文件中会有多个控件,所以我一般推荐是用一些像是CheckableLinearLayout进行包裹住这些控件,至于CheckabeRelativeLayout,CheckableFrameLayout这样的看情况吧。其中,CheckableImageView主要是用于item中有imageview的情况,有的话就把imageview替换为这个吧。

    example01:

    <?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,否则不会有选中的效果!!! -->
        
        ……
        …… 这里放其他的控件
        …… </com.manuelpeinado.multichoiceadapter.view.CheckableLinearLayout>

    这里还需要注意,我们应该在这个控件的background属性中定义一个selector,用于表示选择的状态。如果这里不进行设置,那么就要在代码中进行设置,我个人推荐还是在这里进行设置吧。因为选择效果的话一般是没有太大变动的需求的。

    example02:

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

    上面这个例子是用作一个类似于瀑布流那样的,全是图片的多选界面的。顺便说下CheckableTextView在android中已经提供了,可以直接使用。其实说白了,这些控件就是实现了Checkable接口而已,没太大特别的地方。下面贴个源码,比较能有直观的理解。

    CheckableImageView.java源码

    package com.manuelpeinado.multichoiceadapter.view;
    
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Canvas;
    import android.graphics.drawable.StateListDrawable;
    import android.util.AttributeSet;
    import android.widget.Checkable;
    import android.widget.ImageView;
    
    import com.manuelpeinado.multichoiceadapter.R;
    
    
    public class CheckableImageView extends ImageView implements Checkable {
        private static final int[] CHECKED_STATE_SET = { android.R.attr.state_checked };
        private StateListDrawable stateList;
        private boolean mChecked;
    
        public CheckableImageView(Context context) {
            super(context);
        }
    
        public CheckableImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CheckableImageView,
                    R.attr.checkableImageViewStyle, R.style.MultiChoiceAdapter_DefaultCheckableImageViewStyle);
            stateList = (StateListDrawable)a.getDrawable(R.styleable.CheckableImageView_android_foreground);
            a.recycle();
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            if (stateList != null) {
                stateList.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
                stateList.draw(canvas);
            }
        }
    
        /**************************/
        /** Checkable **/
        /**************************/
    
        @Override
        public boolean isChecked() {
            return mChecked;
        }
    
        @Override
        public void setChecked(boolean checked) {
            if (mChecked != checked) {
                mChecked = checked;
                refreshDrawableState();
            }
        }
    
        @Override
        public void toggle() {
            setChecked(!isChecked());
        }
    
        /**************************/
        /** Drawable States **/
        /**************************/
    
        @Override
        public int[] onCreateDrawableState(int extraSpace) {
            final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
            if (isChecked()) {
                mergeDrawableStates(drawableState, CHECKED_STATE_SET);
            }
            return drawableState;
        }
    
        @Override
        protected void drawableStateChanged() {
            super.drawableStateChanged();
    
            if (stateList != null) {
                int[] myDrawableState = getDrawableState();
                stateList.setState(myDrawableState);
                invalidate();
            }
        }
    }

    二、适配器和接口

    详细解释 ↓:

    监听器源码

    OnSelectedStateChangeListener.java

    package com.manuelpeinado.multichoiceadapter.base;
    
    /**
     * @author:Jack Tony
     * @tips  :监听适配器选中item状态的监听器
     * @date  :2014-10-20
     */
    public interface OnSelectedStateChangeListener {
    
         /**
         * @param checkedItemCount 已经选中的item数目
         */
        public void onSelectedStateChanged(int checkedItemCount) ;
    }

    其余的源码请下载项目后自行查看,我主要改的是helper中的内容,改的比较多可以和原来项目对比着看看。

    三、适配器用法

    现在我们已经看到了它提供了三个适配器MultiChoiceArrayAdapter,MultiChoiceBaseAdapter,MultiChoiceSimpleCursorAdapter。还有一个我自己写的MulitChoiceNormalArrayAdapter(简单实现了MultiChoiceArrayAdapter,用法之后会说到),我们很容易和常用的适配器进行联系起来。但是它的用法是十分奇葩的,略微诡异。

    String[] data = {"android","ios","wp","c++","java","c#","javascript","vb","delphi","PB","ASP","SQL"};
    
    ListView actionModelistView = (ListView)findViewById(R.id.actionMode_listView);
    
    actionModeAdapter = new TestAdapter(savedInstanceState, this,R.layout.item, R.id.item_textView, data);
    actionModeAdapter.setAdapterView(actionModelistView);
    actionModeAdapter.setOnItemClickListener(new MyItemClick(actionModeAdapter));

    String[] data = {"android","ios","wp","c++","java","c#","javascript","vb","delphi","PB","ASP","SQL"};

    ListView actionModelistView = (ListView)findViewById(R.id.actionMode_listView);

    actionModeAdapter = new TestAdapter(savedInstanceState, this,R.layout.item, R.id.item_textView, data);//初始化
    actionModeAdapter.setAdapterView(actionModelistView);//不用listview的setAdapter,而是让适配器来setView
    actionModeAdapter.setOnItemClickListener(new MyItemClick(actionModeAdapter));//连添加监听器也是用适配器进行添加的

    下面的几篇文章中会用到ActionMode的配置文件

    在res->values->menu下建立一个my_action_mode.xml文件

    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <item
            android:id="@+id/menu_share"
            android:icon="@drawable/ic_social_share"
            android:showAsAction="always"
            android:title="分享"/>
        <item
            android:id="@+id/menu_discard"
            android:icon="@drawable/ic_content_discard"
            android:showAsAction="always"
            android:title="取消选择"/>
    
    </menu>

    开源项目下载:http://download.csdn.net/detail/shark0017/8065279

    注:里面以Lib_xxx开头的就是我自己修改的,另一个是原始文件。

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

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

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

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

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

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

  • 相关阅读:
    C# 之 HttpRequest 类
    C# 之 日常问题积累(一)
    DataGrid前台数据绑定技巧
    [转]C,C++开源项目中的100个Bugs
    10行Python代码解决约瑟夫环(模拟)
    基于ASP.NET的comet简单实现 http长连接,IAsyncResult
    架构设计分享之权限系统(看图说话)
    内核request_mem_region 和 ioremap的理解
    【调侃】IOC前世今生 工厂模式 反射 依赖倒置
    ecos内核概览--bakayi译
  • 原文地址:https://www.cnblogs.com/tianzhijiexian/p/4041400.html
Copyright © 2011-2022 走看看