ListView 选择模式
2016-04-23 17:30
405 查看
实际的应用APP开发中,基本上由自己来控制多选的逻辑,后来参考大神的作品,发现ListView本身已经实现了,下面就跟随我的足迹,一起探讨一下吧。
ListView四种模式
AbsListView对多选的支持
由于本人现在水平比较低,就不讲理论了免得误人子弟,下面讲述一下他们的用法吧,让大家有一个感性的认识。
为了突出关键代码,咱们将所有模式都用到的材料在这里定义一下。
MyAdapter.java
在这里强调一下:该模式下,用户选择任意一项后,界面不会自动刷新(这里也就是不会将选中的项自动设置为选中项的颜色),用户点击任意一项会同时触发onItemClick,在这里面刷新界面就ok了。最后要获取所有数据的时候,使用getCheckedItemPositions()就ok啦!
当长按item 或者是主动调用setItemChecked方法mChoiceActionMode将被实例化,进入actionmode状态。为了让ListView自动进入多选状态,可以通过以下方法,进入多选状态而不选中任何一项。
list_multi_select_actionbar.xml 标题栏布局文件
用到的几个参数
Java代码:
这里有几个问题需要注意一下:
1.进入页面没有点击标题栏的时候,点击ListView任意一项仅仅是点击——onItemClick会调用;
2.点击标题栏“更多”->“多选”后,调用onOptionsItemSelected方法
ListView进入多选模式;
3.ListView进入多选模式后,调用onCreateActionMode创建新的标题栏;
4.ListView.MultiChoiceModeListener onCreateActionMode/onPrepareActionMode/onOptionsItemSelected和Activity的onCreateOptionsMenu/onPrepareOptionsMenu/onActionItemClicked用法一样。
5.
中, mListView.setItemChecked(0, false);和onOptionsItemSelected中mListView.setItemChecked(0, true);遥相呼应,ListView退出多选模式。
本文核心内容参考地址:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1105/1906.html
Demo下载地址:
http://download.csdn.net/detail/guchuanhang/9500350
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; import android.annotation.TargetApi; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Build; import android.support.v4.content.res.ResourcesCompat; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ListView; import android.widget.TextView; @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public class MyAdapter extends BaseAdapter { private Context mContext; private ListView mListView; private Drawable mUnCheckedDrawable; private Drawable mCheckedDrawable; private String[] mStrings = { "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Anthoriro" }; public MyAdapter(Context context, ListView list) { mContext = context; mListView = list; mCheckedDrawable = ResourcesCompat.getDrawable(context.getResources(), R.drawable.list_selected_holo_light, null); mUnCheckedDrawable = ResourcesCompat.getDrawable( context.getResources(), R.drawable.conversation_item_background_read, null); } 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]); int sdk = android.os.Build.VERSION.SDK_INT; if (mListView.isItemChecked(position)) { if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) { tv.setBackgroundDrawable(mCheckedDrawable); } else { tv.setBackground(mCheckedDrawable); } } else { if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) { tv.setBackgroundDrawable(mUnCheckedDrawable); } else { tv.setBackground(mUnCheckedDrawable); } } 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
相关文章推荐
- UI控件--桌面小组件(1)
- php环境搭建wampserver、Apache、Mysql和php
- 字符串处理------旋转
- C#第八周异常处理
- union与enum数据结构
- android 常用color代码
- 用开源项目SwitchButton实现各种风格的switch
- [改善Java代码]优先使用整型池
- idea java complier 解决 版本老变
- 如何学好PHP
- java 交换链表中所有相邻结点的顺序
- java反射
- linux信号处理、killall、SIGALRM、sigaction函数和结构体、向进程发送信号
- Bsoj 1322 【练习试题】第K小数
- 关于maven:调整你的maven的jdk版本为 xxxx
- 解决eclipse j2ee struts2环境搭建问题
- Android自定义View实战-100行带你写出SwitchButton
- PHP基础常见问题
- project 修改实际完成时间 计划完成时间自动也修改了 解决办法
- 单链表的逆转