ListView单选多选
来源:互联网 发布:vr编辑软件 编辑:程序博客网 时间:2024/06/03 11:16
Android中,ListView可以设置choiceMode,可见Android对ListView的单选或多选是有进行封装的,然而我看到的许多单选或多选的ListView,包括我搭档以前写的例子,以前几个老外封装的库,都是自己维护了一个集合,用于存放每个item的选中状态。这样一来,不但代码显得繁复,逻辑上也成冗余,而且容易出BUG。
其实,ListView中,已经自己维护了一个SparseBooleanArray,用于保存每一项的选中状态。而对于每一项,它是通过adapter的getView中获取的view,来设置它的选中状态的。所以,我们需要使得adapter中,getView中返回的这个view实现Checkable接口。下面,将介绍具体实现。
要想实现单选和多选首先这个item的布局很重要
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <RadioButton android:id="@+id/checkedView" android:layout_centerVertical="true" android:layout_alignParentLeft="true" android:layout_width="wrap_content" android:layout_height="48dp" /> <TextView android:id="@+id/text" android:gravity="center_vertical" android:layout_alignParentRight="true" android:layout_width="wrap_content" android:layout_height="48dp" /></RelativeLayout>
自定义的布局
import android.content.Context;import android.view.View;import android.widget.Checkable;import android.widget.FrameLayout;import android.widget.RadioButton;import android.widget.TextView;/** * Created by xuenan on 2016/7/13. */public class ChoiceView extends FrameLayout implements Checkable{ private TextView mTextView; private RadioButton mRadioButton; public ChoiceView(Context context) { super(context); View.inflate(context, R.layout.item_single_choice, this); mTextView = (TextView) findViewById(R.id.text); mRadioButton = (RadioButton) findViewById(R.id.checkedView); } public void setText(String text) { mTextView.setText(text); } @Override public void setChecked(boolean checked) { mRadioButton.setChecked(checked); } @Override public boolean isChecked() { return mRadioButton.isChecked(); } @Override public void toggle() { mRadioButton.toggle(); }}
还有Adapter中的处理
import android.content.Context;import android.util.SparseArray;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.Checkable;import android.widget.FrameLayout;import android.widget.TextView;import java.util.Arrays;import java.util.List;/** * 可选择的ListAdapter. */public abstract class ChoiceListAdapter<T> extends BaseAdapter { private Context mContext; protected List<T> mData; private int mLayoutId; private int[] mChoiceId; /** * @param context * @param layoutId item 的布局id. * @param data 数据源 * @param choiceId 选择控件的id */ public ChoiceListAdapter(Context context, int layoutId, List<T> data, int... choiceId) { mContext = context; mData = data; mLayoutId = layoutId; mChoiceId = choiceId; } /** * @param context * @param layoutId The layout id if the item view. * @param data data source * @param choiceId checkable view id */ public ChoiceListAdapter(Context context, int layoutId, T[] data, int... choiceId) { this(context, layoutId, Arrays.asList(data), choiceId); } @Override public int getCount() { return mData == null ? 0 : mData.size(); } @Override public T getItem(int position) { return mData == null ? null : mData.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { final ChoiceLayout view; if (convertView == null) { view = new ChoiceLayout(mContext); view.setLayoutAndChoiceId(mLayoutId, mChoiceId); holdView(view); } else { view = (ChoiceLayout) convertView; } bindData(view, position, mData.get(position)); return view; } /** * 持有item的子view。在该方法内调用ChoiceView的hold方法,把子view添加进去。 * * @param view ChoiceView */ protected abstract void holdView(ChoiceLayout view); /** * 绑定数据 * * @param view * @param position * @param data */ protected abstract void bindData(ChoiceLayout view, int position, T data); /** * 绑定Checkable控件的Layout. */ public static class ChoiceLayout extends FrameLayout implements Checkable { private Checkable[] mCheckViews; private SparseArray<View> mHolderViews; private boolean mChecked; /** * 是否强制设为选中状态 */ private boolean mForceChecked; protected ChoiceLayout(Context context) { super(context); mHolderViews = new SparseArray<>(); } /** * 设置item的布局及Checkable控件的id。 * * @param layoutId 布局id * @param choiceId Checkable控件id */ protected void setLayoutAndChoiceId(int layoutId, int... choiceId) { View.inflate(getContext(), layoutId, this); mCheckViews = new Checkable[choiceId.length]; for (int i = 0; i < choiceId.length; i++) { View checkedView = findViewById(choiceId[i]); checkedView.setFocusable(false); checkedView.setFocusableInTouchMode(false); checkedView.setClickable(false); mHolderViews.put(choiceId[i], checkedView); mCheckViews[i] = (Checkable) checkedView; } } /** * 持有子view * * @param id */ public void hold(int id) { mHolderViews.put(id, findViewById(id)); } /** * 获取子view。 * * @param id * @param <V> * @return 返回指定的id对应的view。 */ public <V> V get(int id) { return (V) mHolderViews.get(id); } public void setText(int id, int stringId) { TextView textView = get(id); textView.setText(stringId); } public void setText(int id, String text) { TextView textView = get(id); textView.setText(text); } public void setChecked(int id, boolean checked) { Checkable checkable = get(id); checkable.setChecked(checked); } @Override public void setChecked(boolean checked) { checked |= mForceChecked; for (Checkable checkable : mCheckViews) { checkable.setChecked(checked); } mChecked = checked; } @Override public boolean isChecked() { return mChecked; } /** * 是否为强制选中状态。 * * @return 如果是强制选中状态返回true,否则返回false。 */ public boolean isForceChecked() { return mForceChecked; } /** * 设置是否强制选中状态。 * * @param forceChecked 是否强制选中状态。 */ public void setForceChecked(boolean forceChecked) { mForceChecked = forceChecked; } @Override public void toggle() { setChecked(mForceChecked | !mChecked); } }}
单选模式的使用,布局里边就一个listView就不贴了
import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.AdapterView;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;import java.util.List;public class SingleActivity extends AppCompatActivity { private ListView mListView; private ChoiceListAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.activity_choice_list2); mListView = (ListView) findViewById(android.R.id.list); mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);//设置单选模式 List<String> data = new ArrayList<>(); for (int i = 0; i < 5; i++) { data.add("test" + i); } adapter = new ChoiceListAdapter<String>(this, R.layout.item_single_choice, data, R.id.checkedView) { @Override protected void holdView(ChoiceLayout view) { view.hold(R.id.text); } @Override protected void bindData(ChoiceLayout view, int position, String data) { TextView text = view.get(R.id.text); text.setText(data); } }; mListView.setAdapter(adapter); mListView.setItemChecked(0,true);//设置默认选中第一个 mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (ListView.CHOICE_MODE_SINGLE == mListView.getChoiceMode()) { String item_data = (String) mListView .getItemAtPosition(position); Toast.makeText(SingleActivity.this, "当前为单选模式\n选中条目的数据:" + item_data,Toast.LENGTH_SHORT).show(); } } }); }}
//多选模式的使用布局中一个listView 两个按钮 也不写了
import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.util.SparseBooleanArray;import android.view.View;import android.widget.AdapterView;import android.widget.ListView;import android.widget.TextView;import android.widget.Toast;import java.util.ArrayList;import java.util.List;public class MultActivity extends AppCompatActivity { private View mChoiceAll; private View mReverseChoice; private ListView mListView; private ChoiceListAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.activity_choice_list); mChoiceAll = findViewById(R.id.all); mReverseChoice = findViewById(R.id.reverse); mListView = (ListView) findViewById(android.R.id.list); mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);//设置多选模式 List<String> data = new ArrayList<>(); for (int i = 0; i < 5; i++) { data.add("test" + i); } adapter = new ChoiceListAdapter<String>(this, R.layout.item_single_choice, data, R.id.checkedView) { @Override protected void holdView(ChoiceLayout view) { view.hold(R.id.text); } @Override protected void bindData(ChoiceLayout view, int position, String data) { TextView text = view.get(R.id.text); text.setText(data); } }; mListView.setAdapter(adapter); //全选 mChoiceAll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final int size = adapter.getCount(); for (int i = 0; i < size; i++) { mListView.setItemChecked(i, true); } Toast.makeText( MultActivity.this, "当前为多选模式\n选中的条数:" + mListView.getCheckedItemCount(), Toast.LENGTH_SHORT).show(); SparseBooleanArray sparseBooleanArray = mListView.getCheckedItemPositions(); ArrayList<String> list = GetPOsitions(sparseBooleanArray); for (int i = 0; i < list.size(); i++) { Log.e("------", list.get(i)); } } }); //反选 mReverseChoice.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { SparseBooleanArray checkedItems = mListView.getCheckedItemPositions(); final int size = adapter.getCount(); for (int i = 0; i < size; i++) { mListView.setItemChecked(i, !checkedItems.get(i)); } } }); mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { if (ListView.CHOICE_MODE_MULTIPLE == mListView.getChoiceMode()) { String item =(String) mListView.getItemAtPosition(position); Toast.makeText( MultActivity.this, "当前为多选模式\n选中的条数:" + mListView.getCheckedItemCount() + "\n" + "点击的数据:" + item,Toast.LENGTH_SHORT) .show(); SparseBooleanArray sparseBooleanArray = mListView.getCheckedItemPositions(); ArrayList<String> list = GetPOsitions(sparseBooleanArray); for(int i=0;i<list.size();i++){ Log.e("------",list.get(i)); } } } }); } //保存选中项的方法 private ArrayList<String> GetPOsitions(SparseBooleanArray sparseBooleanArray){ ArrayList<String>strings = new ArrayList<>(); String sss = sparseBooleanArray.toString(); String sss_s = sss.substring(1,sss.length()-1); String [] xx = sss_s.split(","); for(int j=0;j<xx.length;j++){ if(xx[j].contains("true")){ strings.add(xx[j].trim().substring(0,xx[j].trim().length()-5)); } } return strings; }}
0 0
- ListView单选多选
- android listview 单选多选 selector
- listView 实现单选多选
- PullToRefreshListView listview 单选多选
- listview
- listview
- listview
- ListView
- ListView
- listview
- listview
- listView
- ListView
- ListView
- ListView
- listview
- LIstView
- ListView
- C语言 获取字符串的方法
- C#new和override的区别
- C#/.net学习-----C#基础知识-对象和类型
- 如何快速调节CorelDRAW中位图图像颜色
- 个性化定制分享功能
- ListView单选多选
- 通过openOptionsMenu无法打开optionsMenu问题的一种解决可能
- 如何取得View的位置之View.getLocationInWindow()的小秘密
- CSS 和 JS 动画哪个会更快
- JavaWeb学习总结(一)——JavaWeb开发入门
- 基于深度学习的目标检测研究进展
- Sql Server Md5使用
- Springmvc 使用 poi 读取excel
- Mac 安装CocoaPods过程以及遇到Ruby问题解决方案