這段時間在些項目時發現一個小技術點還是挺有意思的,特來總結一下,就是如何在ListView的item中自己寫了一個checkbox,那麼如何獲取到這個item的checkbox的選中事件,進而怎樣操作,比方說點擊全選、取消後如何讓checkbox被選擇或者是取消,我們來一起學習一下。
先上代碼
<?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"
android:padding="25dp"
android:layout_centerVertical="true">
<ImageView
android:id="@+id/iv_app_icon"
android:src="@mipmap/ic_launcher"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_centerVertical="true"/>
<TextView
android:id="@+id/tv_app_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/iv_app_icon"
android:layout_centerVertical="true"
android:text="微信"
android:paddingLeft="18dp"
android:textSize="15dp"/>
<CheckBox
android:id="@+id/cb_app_uninstall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:focusable="false"
android:clickable="false"/>
</RelativeLayout>
大家可以看到我將checkbox命名爲cb_app_uninstall,其實主要是一個與卸載相關的選中鍵,然後我將adapter與holder提取出來單獨封裝爲一個類
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import java.util.ArrayList;
//這個是自定義的adpter的基類
public class MyBaseAdapter<T> extends BaseAdapter {
private ArrayList<T> dataList;
private Context mContext;
LayoutInflater inflater;
public MyBaseAdapter(Context context,ArrayList<T> dataList){
this.mContext = context;
this.dataList = dataList;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {
return dataList.size();
}
@Override
public Object getItem(int position) {
return dataList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
}
下面是我單獨提取出來的AppManagerAdapter
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import com.qingcheng.mobilemanager.R;
import com.qingcheng.mobilemanager.bean.AppInfo;
import com.qingcheng.mobilemanager.holder.AppViewholder;
import java.util.ArrayList;
import java.util.List;
public class AppManagerAdapter extends MyBaseAdapter<AppInfo> {
private Context mContext;
private ArrayList<AppInfo> mDatas;
public List<Boolean> mChecked;
public AppManagerAdapter(Context context, ArrayList<AppInfo> dataList) {
super(context, dataList);
this.mContext = context;
this.mDatas = dataList;
mChecked = new ArrayList<Boolean>();
for (int i = 0; i < dataList.size(); i++){
mChecked.add(false);
}
}
@Override
public AppInfo getItem(int position) {
return mDatas.get(position);
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
AppViewholder holder ;
if (convertView == null){
convertView = View.inflate(mContext,R.layout.list_item_app_manager,null);
holder = new AppViewholder();
holder.ivAppIcon = (ImageView)convertView.findViewById(R.id.iv_app_icon);
holder.tvAppName = (TextView) convertView.findViewById(R.id.tv_app_name);
holder.cbAppUninstall = (CheckBox) convertView.findViewById(R.id.cb_app_uninstall);
convertView.setTag(holder);
}else{
holder = (AppViewholder) convertView.getTag();
}
AppInfo info = getItem(position);
holder.ivAppIcon.setImageDrawable(info.appIcon);
holder.tvAppName.setText(info.appName);
holder.cbAppUninstall.setChecked(mChecked.get(position));
return convertView;
}
}
BaseHolder是holder的基類
import android.view.View;
public abstract class BaseHolder<T> {
public View convertView;
public T mData;
public BaseHolder(){
convertView = initView();
convertView.setTag(this);
}
public abstract View initView();
public void setData(T data){
mData = data;
}
}
這個是我抽取出來的AppViewholder
import android.view.View;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import com.qingcheng.mobilemanager.R;
import com.qingcheng.mobilemanager.bean.AppInfo;
import com.qingcheng.mobilemanager.utils.UiUtils;
public class AppViewholder extends BaseHolder<AppInfo> {
public ImageView ivAppIcon;
public TextView tvAppName;
public CheckBox cbAppUninstall;
@Override
public View initView() {
View view = UiUtils.inflate(R.layout.list_item_app_manager);
ivAppIcon = (ImageView) view.findViewById(R.id.iv_app_icon);
tvAppName = (TextView) view.findViewById(R.id.tv_app_name);
cbAppUninstall = (CheckBox) view.findViewById(R.id.cb_app_uninstall);
return view;
}
@Override
public void setData(AppInfo data) {
super.setData(data);
tvAppName.setText(mData.appName);
}
}
好了,現在來說說我們的正事,如何獲取listview中checkbox的選中事件
首先不知道大家有沒有注意到我在AppManagerAdapter中設置了一個
public List<Boolean> mChecked;
mChecked集合 就是一切的關鍵
//先在AppManagerAdapter中定義mChecked的長度並賦值
mChecked = new ArrayList<Boolean>();
for (int i = 0; i < dataList.size(); i++){
mChecked.add(false);
}
然後在getView中set
holder.cbAppUninstall.setChecked(mChecked.get(position));
再在Activity中對listView的item獲取點擊事件,先要對listView設置監聽,並對checkbox的點擊事件設置爲
android:focusable="false"
android:clickable="false"
如果不這麼設置會讓listView的item得不到點擊事件
/**
* 每個item被點擊監聽
*/
lvAppDisplay.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (mAdapter.mChecked.get(position)){
mAdapter.mChecked.set(position,false);
}else if (!mAdapter.mChecked.get(position)){
mAdapter.mChecked.set(position,true);
}
mAdapter.notifyDataSetChanged();
}
});
這樣就可以及時獲取checkbox的點擊事件並及時更新控制他們的mChecked的狀態
當想要點擊一個類似全選的按鈕達到全選的效果時可以這樣做
private boolean checkedAll = false;
/**
* 全選事件
*/
tvCheckAll.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (!checkedAll){
for (int i = 0; i < mDatas.size(); i++){
mAdapter.mChecked.set(i,true);
}
checkedAll = true;
mAdapter.notifyDataSetChanged();
}else{
for (int i = 0; i < mDatas.size(); i++){
mAdapter.mChecked.set(i,false);
}
checkedAll = false;
mAdapter.notifyDataSetChanged();
}
}
});
這樣就完美實現了在全選和全部取消之間的切換,從而我們就可以另一個方法中獲取被選中item的position
for (int i = 0;i< mAdapter.mChecked.size();i++){
if (mAdapter.mChecked.get(i)){
//listItemID爲被選中item的position
listItemID.add(i);
}
}