ListView 选择模式

来源:互联网 发布:阿里云怎么退款 编辑:程序博客网 时间:2024/06/11 06:23

实际的应用APP开发中,基本上由自己来控制多选的逻辑,后来参考大神的作品,发现ListView本身已经实现了,下面就跟随我的足迹,一起探讨一下吧。

  • ListView四种模式
  /**     * Normal list that does not indicate choices     */    public static final int CHOICE_MODE_NONE = 0;    /**     * The list allows up to one choice     */    public static final int CHOICE_MODE_SINGLE = 1;    /**     * The list allows multiple choices     */    public static final int CHOICE_MODE_MULTIPLE = 2;    /**     * The list allows multiple choices in a modal selection mode     */    public static final int CHOICE_MODE_MULTIPLE_MODAL = 3;
  • AbsListView对多选的支持
 /**     * Returns the checked state of the specified position. The result is only     * valid if the choice mode has been set to {@link #CHOICE_MODE_SINGLE}     * or {@link #CHOICE_MODE_MULTIPLE}.     *     * @param position The item whose checked state to return     * @return The item's checked state or <code>false</code> if choice mode     *         is invalid     *     * @see #setChoiceMode(int)     */    public boolean isItemChecked(int position) {        if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null) {            return mCheckStates.get(position);        }        return false;    }
 /**     * Returns the number of items currently selected. This will only be valid     * if the choice mode is not {@link #CHOICE_MODE_NONE} (default).     *     * <p>To determine the specific items that are currently selected, use one of     * the <code>getChecked*</code> methods.     *     * @return The number of items currently selected     *     * @see #getCheckedItemPosition()     * @see #getCheckedItemPositions()     * @see #getCheckedItemIds()     */    public int getCheckedItemCount() {        return mCheckedItemCount;    }
 /**     * Sets the checked state of the specified position. The is only valid if     * the choice mode has been set to {@link #CHOICE_MODE_SINGLE} or     * {@link #CHOICE_MODE_MULTIPLE}.     *     * @param position The item whose checked state is to be checked     * @param value The new checked state for the item     */    public void setItemChecked(int position, boolean value) {        if (mChoiceMode == CHOICE_MODE_NONE) {            return;        }        ...
  /**     * Clear any choices previously set     */    public void clearChoices() {        if (mCheckStates != null) {            mCheckStates.clear();        }        if (mCheckedIdStates != null) {            mCheckedIdStates.clear();        }        mCheckedItemCount = 0;    }

由于本人现在水平比较低,就不讲理论了免得误人子弟,下面讲述一下他们的用法吧,让大家有一个感性的认识。
为了突出关键代码,咱们将所有模式都用到的材料在这里定义一下。
MyAdapter.java

package com.example.listmultichoise;package com.scott.crash;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ListView;import android.widget.TextView;public class MyAdapter extends BaseAdapter {    private Context mContext;    private ListView mListView;    private String[] mStrings = {"Abbaye de Belloc",            "Abbaye du Mont des Cats", "Abertam", "Anthoriro"};    public MyAdapter(Context context, ListView list) {        mContext = context;        mListView = list;    }    public int getCount() {        return mStrings.length;    }    public Object getItem(int position) {        return position;    }    public long getItemId(int position) {        return position;    }    @SuppressWarnings("deprecation")    public View getView(int position, View convertView, ViewGroup parent) {        TextView tv;        if (convertView == null) {            tv = (TextView) LayoutInflater.from(mContext).inflate(                    android.R.layout.simple_expandable_list_item_1, parent,                    false);        } else {            tv = (TextView) convertView;        }        tv.setText(mStrings[position]);        if (mListView.isItemChecked(position)) {            tv.setBackgroundResource(android.R.color.holo_red_dark);        } else {            tv.setBackgroundResource(android.R.color.white);        }        return tv;    }}

ListView.CHOICE_MODE_MULTIPLE

package com.example.listmultichoise;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ListView;public class ChoiceModeMultipleActivity extends Activity {    ListView mListView = null;    MyAdapter mAdapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        mListView = new ListView(this);        setContentView(mListView);        mAdapter = new MyAdapter(this, mListView);        mListView.setAdapter(mAdapter);        // 设置为多选模式        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);        mListView.setOnItemClickListener(new OnItemClickListener() {            // 用户在选择的时候,也会调用该方法,在该方法中调用notifyDataSetChanged刷新选中状态            public void onItemClick(AdapterView<?> parent, View view,                    int position, long id) {                mAdapter.notifyDataSetChanged();            }        });    }}

在这里强调一下:该模式下,用户选择任意一项后,界面不会自动刷新(这里也就是不会将选中的项自动设置为选中项的颜色),用户点击任意一项会同时触发onItemClick,在这里面刷新界面就ok了。最后要获取所有数据的时候,使用getCheckedItemPositions()就ok啦!

ListView.CHOICE_MODE_MULTIPLE_MODAL

该模式在Android3.0(APIs 11)引入,逻辑有点复杂。多选和onItemClick不能同时触发。CHOICE_MODE_MULTIPLE_MODAL结合actionmode,当启动actionmode(不能在activity中调用startActionMode)时进入多选状态,退出/未进入就是普通的点击行为(即仅仅调用onItemClick)。
当长按item 或者是主动调用setItemChecked方法mChoiceActionMode将被实例化,进入actionmode状态。为了让ListView自动进入多选状态,可以通过以下方法,进入多选状态而不选中任何一项。

if(item.getItemId() == R.id.action_choice){     mListView.setItemChecked(0,true);     mListView.clearChoices();}

list_multi_select_actionbar.xml 标题栏布局文件

<LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/custom_title_root"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal">    <TextView        android:id="@+id/title"        android:maxLines="1"        android:singleLine="true"        android:layout_gravity="center_vertical"        android:layout_centerVertical="true"        android:textAppearance="?android:attr/textAppearanceMediumInverse"        android:layout_weight="1"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <TextView        android:id="@+id/selected_conv_count"        android:maxLines="1"        android:singleLine="true"        android:textAppearance="?android:attr/textAppearanceLarge"        android:textColor="#ccffffff"        android:layout_gravity="center_vertical"        android:paddingRight="10dip"        android:layout_width="wrap_content"        android:layout_height="wrap_content" /></LinearLayout>

用到的几个参数

 <string name="action_settings">多选</string>    <string name="select_item">已选择:</string>    <string name="action_select_all">全选</string>    <string name="action_deselect_all">全不选</string>

Java代码:

package com.example.listmultichoise;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.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;public class ChoiceModeMultipleModalActivity extends Activity {    ListView mListView = null;    MyAdapter mAdapter;    ModeCallback mCallback;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        mListView = new ListView(this);        setContentView(mListView);        mAdapter = new MyAdapter(this, mListView);        mListView.setAdapter(mAdapter);        mCallback = new ModeCallback();        mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);        mListView.setMultiChoiceModeListener(mCallback);        mListView.setOnItemClickListener(new OnItemClickListener() {            public void onItemClick(AdapterView<?> parent, View view,                    int position, long id) {                Toast.makeText(ChoiceModeMultipleModalActivity.this,                        "" + position, Toast.LENGTH_LONG).show();            }        });    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.main, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        if (item.getItemId() == R.id.action_choice) {            mListView.setItemChecked(0, true);            mListView.clearChoices();            mCallback.updateSeletedCount();        }        return super.onOptionsItemSelected(item);    }    private class ModeCallback implements ListView.MultiChoiceModeListener {        private View mMultiSelectActionBarView;        private TextView mSelectedCount;        @Override        public boolean onCreateActionMode(ActionMode mode, Menu menu) {            MenuInflater inflater = getMenuInflater();            inflater.inflate(R.menu.multi_select_menu, menu);            if (mMultiSelectActionBarView == null) {                mMultiSelectActionBarView = LayoutInflater.from(                        ChoiceModeMultipleModalActivity.this).inflate(                        R.layout.list_multi_select_actionbar, null);                mSelectedCount = (TextView) mMultiSelectActionBarView                        .findViewById(R.id.selected_conv_count);            }            mode.setCustomView(mMultiSelectActionBarView);            ((TextView) mMultiSelectActionBarView.findViewById(R.id.title))                    .setText(R.string.select_item);            return true;        }        @Override        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {            MenuItem mItem = menu.findItem(R.id.action_slelect);            if (mListView.getCheckedItemCount() == mAdapter.getCount()) {                mItem.setTitle(R.string.action_deselect_all);            } else {                mItem.setTitle(R.string.action_select_all);            }            return true;        }        @Override        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {            switch (item.getItemId()) {            case R.id.action_slelect:                if (mListView.getCheckedItemCount() == mAdapter.getCount()) {                    unSelectedAll();                } else {                    selectedAll();                }                mAdapter.notifyDataSetChanged();                break;            default:                break;            }            return true;        }        @Override        public void onDestroyActionMode(ActionMode mode) {            mListView.clearChoices();        }        @Override        public void onItemCheckedStateChanged(ActionMode mode, int position,                long id, boolean checked) {            updateSeletedCount();            mode.invalidate();            mAdapter.notifyDataSetChanged();        }        public void updateSeletedCount() {            mSelectedCount.setText(Integer.toString(mListView                    .getCheckedItemCount()));        }    }    public void selectedAll() {        for (int i = 0; i < mAdapter.getCount(); i++) {            mListView.setItemChecked(i, true);        }        mCallback.updateSeletedCount();    }    public void unSelectedAll() {        mListView.clearChoices();        mListView.setItemChecked(0, false);        mCallback.updateSeletedCount();    }}

这里有几个问题需要注意一下:
1.进入页面没有点击标题栏的时候,点击ListView任意一项仅仅是点击——onItemClick会调用;
2.点击标题栏“更多”->“多选”后,调用onOptionsItemSelected方法

    mListView.setItemChecked(0, true);            mListView.clearChoices();

ListView进入多选模式;
3.ListView进入多选模式后,调用onCreateActionMode创建新的标题栏;
4.ListView.MultiChoiceModeListener onCreateActionMode/onPrepareActionMode/onOptionsItemSelected和Activity的onCreateOptionsMenu/onPrepareOptionsMenu/onActionItemClicked用法一样。
5.

    public void unSelectedAll() {        mListView.clearChoices();        mListView.setItemChecked(0, false);        mCallback.updateSeletedCount();    }

中, mListView.setItemChecked(0, false);和onOptionsItemSelected中mListView.setItemChecked(0, true);遥相呼应,ListView退出多选模式。

ListView.CHOICE_MODE_SINGLE

package com.example.listmultichoise;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView.OnItemClickListener;import android.widget.AdapterView;import android.widget.ListView;public class ChoiceModeSingleActivity extends Activity implements        OnItemClickListener {    private ListView listView;    private MyAdapter adapter;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        listView = new ListView(this);        setContentView(listView);        adapter = new MyAdapter(this, listView);        listView.setAdapter(adapter);        listView.setOnItemClickListener(this);        listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);    }    @Override    public void onItemClick(AdapterView<?> parent, View view, int position,            long id) {        adapter.notifyDataSetChanged();        int checkedPosition = listView.getCheckedItemPosition();        System.err.println();    }}

ListView.CHOICE_MODE_NONE

package com.example.listmultichoise;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.AdapterView.OnItemClickListener;import android.widget.AdapterView;import android.widget.ListView;import android.widget.Toast;public class ChoiceModeNoneActivity extends Activity implements        OnItemClickListener {    private ListView listView;    private MyAdapter adapter;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        listView = new ListView(this);        setContentView(listView);        adapter = new MyAdapter(this, listView);        listView.setAdapter(adapter);        listView.setOnItemClickListener(this);        // 这个是默认模式,写不写无所谓        listView.setChoiceMode(ListView.CHOICE_MODE_NONE);    }    @Override    public void onItemClick(AdapterView<?> parent, View view, int position,            long id) {        Toast.makeText(this, position + "", Toast.LENGTH_LONG).show();    }}

本文核心内容参考地址:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1105/1906.html
Demo下载地址:
http://download.csdn.net/detail/guchuanhang/9500350

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 我宝宝的牙齿长的不整齐怎么办? 宝宝5个月了母乳不够吃怎么办 4个月宝宝母乳不够吃怎么办 11个月宝宝只吃母乳怎么办 10个月宝宝突然不吃母乳怎么办 2个月宝宝咳嗽怎么办是吃母乳的 九个月宝宝不喜欢吃粥和米糊怎么办 9个月宝宝突然不吃辅食怎么办 宝贝8个月不吃辅食怎么办 11个月宝贝不吃辅食怎么办 十一个月宝宝长牙不吃辅食怎么办 八个多月的宝宝不爱吃辅食怎么办 7个月的宝宝不爱吃辅食怎么办 宝宝只吃母乳不吃辅食怎么办 10个月的宝宝不肯吃勺子怎么办 十一个月大宝宝不吃奶吃饭怎么办 十一个月宝宝光吃奶不吃饭怎么办 20个月宝宝爱吃奶不爱吃饭怎么办 宝宝8个多月不肯米糊跟粥怎么办 8个月宝宝突然不肯吃米糊了怎么办 八个月宝宝突然不吃辅食怎么办 八个月宝宝拉屎费劲还干怎么办 两个月的小孩不喜欢吃奶粉怎么办 三个多月的宝宝不爱吃奶怎么办 4个月的宝宝不吃奶怎么办 九个月宝宝一直高烧不退怎么办 8个月宝宝不吃辅食怎么办 孩子七个月了母乳不够了怎么办 11个月宝宝吃的太多怎么办 宝宝十一个月了上火眼死太多怎么办 9个月孩子不吃辅食怎么办 y一夜没有睡好现在母乳不够怎么办 喂母乳的婴儿总要吃奶怎么办 宝宝四个月了奶水不够吃怎么办 宝宝出生十天了奶水不够吃怎么办 宝宝晚上不吃奶了奶水多怎么办 我家小孩六个月了奶不够吃怎么办 六个月的宝宝奶不够吃怎么办 宝贝六个月了奶不够吃怎么办 奶不够吃宝宝又不吃奶粉怎么办 婴儿到新环境哭闹不睡觉怎么办