Android的AlertDialog中可以通过builder.setMultiChoiceItems(....)来添加一个多选项,但是并不能实现对选项的全选/反选功能,所以需要自定义一个控件。原理是通过ListView + CheckBox来实现,实现效果如下。
一、定义布局样式:
首先需要定义多选弹出框的样式,custom_mutiplechoice_view.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="@android:color/background_dark" > <TextView android:id="@+id/mutiplechoice_title" android:layout_width="match_parent" android:layout_height="40dp" android:gravity="center_vertical" android:padding="5dp" android:background="@android:color/darker_gray" android:textSize="18sp" android:textColor="@android:color/black" android:text="标题" /> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:layout_margin="1dp" android:background="@android:color/background_light"> <ListView android:id="@+id/mutiplechoice_listview" android:layout_width="match_parent" android:layout_height="300dp" android:layout_weight="4" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:orientation="horizontal" android:background="@android:color/darker_gray"> <Button android:id="@+id/mutiplechoice_selectall_btn" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="全选" /> <Button android:id="@+id/mutiplechoice_ok_btn" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="确定" /> </LinearLayout> </LinearLayout> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" > <TextView android:id="@+id/item_tv" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_weight="1" android:paddingLeft="10dp" android:textColor="@android:color/black"/> <CheckBox android:id="@+id/item_cb" android:layout_width="wrap_content" android:layout_height="wrap_content" android:clickable="false" android:focusable="false" android:focusableInTouchMode="false" android:gravity="center_vertical" /> </LinearLayout>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="30dp" android:orientation="vertical" android:background="@android:color/background_light"> <com.example.mutichoicedialog.CustomMultipleChoiceView android:id="@+id/CustomMultipleChoiceView" android:layout_width="match_parent" android:layout_height="match_parent" > </com.example.mutichoicedialog.CustomMultipleChoiceView> </LinearLayout>
<RelativeLayout 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" tools:context=".MainActivity" > <EditText android:id="@+id/text" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:onClick="OnViewClick" android:text="显示多选对话框" /> </RelativeLayout>
package com.example.mutichoicedialog; import android.content.Context; import android.util.SparseBooleanArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.TextView; public class MutipleChoiceAdapter extends BaseAdapter { // 填充数据的list private String[] list; // 用来控制CheckBox的选中状况 private SparseBooleanArray isSelected; // 用来导入布局 private LayoutInflater inflater; public MutipleChoiceAdapter(String[] list, Context context) { this.list = list; inflater = LayoutInflater.from(context); isSelected = new SparseBooleanArray(); // 初始化数据 initData(); } // 初始化isSelected的数据 private void initData() { for (int i = 0; i < list.length; i++) { getIsSelected().put(i, false); } } @Override public int getCount() { return list.length; } @Override public Object getItem(int position) { return list[position]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; if (convertView == null) { // 获得ViewHolder对象 holder = new ViewHolder(); // 导入布局并赋值给convertview convertView = inflater.inflate(R.layout.custom_mutiplechoice_view_list_item, null); holder.tv = (TextView) convertView.findViewById(R.id.item_tv); holder.cb = (CheckBox) convertView.findViewById(R.id.item_cb); // 为view设置标签 convertView.setTag(holder); } else { // 取出holder holder = (ViewHolder) convertView.getTag(); } // 设置list中TextView的显示 holder.tv.setText(list[position]); // 根据isSelected来设置checkbox的选中状况 holder.cb.setChecked(getIsSelected().get(position)); return convertView; } public SparseBooleanArray getIsSelected() { return isSelected; } public void setIsSelected(SparseBooleanArray isSelected) { this.isSelected = isSelected; } public static class ViewHolder { TextView tv; public CheckBox cb; } }
package com.example.mutichoicedialog; import com.example.mutichoicedialog.MutipleChoiceAdapter.ViewHolder; import android.content.Context; import android.util.AttributeSet; import android.util.SparseBooleanArray; import android.view.LayoutInflater; import android.view.View; import android.widget.AdapterView; import android.widget.Button; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.AdapterView.OnItemClickListener; import android.widget.TextView; /** * 自定义的带 全选/反选 功能的多选对话框 * @author king * @creation 2013-8-28 */ public class CustomMultipleChoiceView extends LinearLayout { private MutipleChoiceAdapter mAdapter; private String[] data; private TextView title; private ListView lv; private onSelectedListener onSelectedListener;//确定选择监听器 private boolean curWillCheckAll = false;//当前点击按钮时是否将全选 public CustomMultipleChoiceView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public CustomMultipleChoiceView(Context context) { super(context); initView(); } private void initView(){ /* 实例化各个控件 */ LayoutInflater inflater = LayoutInflater.from(getContext()); View view = inflater.inflate(R.layout.custom_mutiplechoice_view, null); lv = (ListView) view.findViewById(R.id.mutiplechoice_listview); Button bt_selectall = (Button) view.findViewById(R.id.mutiplechoice_selectall_btn); Button bt_ok = (Button) view.findViewById(R.id.mutiplechoice_ok_btn); title = (TextView) view.findViewById(R.id.mutiplechoice_title); if(curWillCheckAll){ bt_selectall.setText("全选"); }else{ bt_selectall.setText("反选"); } MyClickListener l = new MyClickListener(); // 全选按钮的回调接口 bt_selectall.setOnClickListener(l); bt_ok.setOnClickListener(l); // 绑定listView的监听器 lv.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { // 取得ViewHolder对象,这样就省去了通过层层的findViewById去实例化我们需要的cb实例的步骤 ViewHolder holder = (ViewHolder) arg1.getTag(); // 改变CheckBox的状态 holder.cb.toggle(); // 将CheckBox的选中状况记录下来 mAdapter.getIsSelected().put(position, holder.cb.isChecked()); } }); // positiveBtn.setOnClickListener(l); addView(view); } public void setData(String[] data, boolean[] isSelected){ if(data == null){ throw new IllegalArgumentException("data is null"); } this.data = data; mAdapter = new MutipleChoiceAdapter(data, getContext()); if(isSelected != null){ if(isSelected.length != data.length){ throw new IllegalArgumentException("data's length not equal the isSelected's length"); }else{ for(int i=0; i<isSelected.length; i++){ mAdapter.getIsSelected().put(i, isSelected[i]); } } } // 绑定Adapter lv.setAdapter(mAdapter); } public void setTitle(String title){ if(this.title != null){ this.title.setText(title); } } public void setOnSelectedListener(onSelectedListener l){ this.onSelectedListener = l; } public interface onSelectedListener{ public void onSelected(SparseBooleanArray sparseBooleanArray); } /** * 全选 */ public void selectAll(){ if(data != null){ for (int i = 0; i < data.length; i++) { mAdapter.getIsSelected().put(i, true); } // 刷新listview和TextView的显示 mAdapter.notifyDataSetChanged(); } } /** * 全不选 */ public void deselectAll(){ if(data != null){ for (int i = 0; i < data.length; i++) { mAdapter.getIsSelected().put(i, false); } // 刷新listview和TextView的显示 mAdapter.notifyDataSetChanged(); } } /** * 反选 */ public void reverseSelect(){ if(data != null){ for (int i = 0; i < data.length; i++) { mAdapter.getIsSelected().put(i, !mAdapter.getIsSelected().get(i)); } // 刷新listview和TextView的显示 mAdapter.notifyDataSetChanged(); } } private class MyClickListener implements OnClickListener{ @Override public void onClick(View v) { switch (v.getId()) { case R.id.mutiplechoice_selectall_btn: //全选/反选按钮 if(data == null){ return; } if(curWillCheckAll){ selectAll(); }else{ deselectAll(); } if(curWillCheckAll){ ((Button)v).setText("反选"); }else{ ((Button)v).setText("全选"); } curWillCheckAll = !curWillCheckAll; break; case R.id.mutiplechoice_ok_btn: //确定选择的按钮 if(onSelectedListener != null && mAdapter != null){ onSelectedListener.onSelected(mAdapter.getIsSelected()); } break; default: break; } } } }
package com.example.mutichoicedialog; import android.app.Activity; import android.os.Bundle; import android.util.SparseBooleanArray; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.View; import android.widget.EditText; import android.widget.LinearLayout.LayoutParams; import android.widget.PopupWindow; import android.widget.TextView; import com.example.mutichoicedialog.CustomMultipleChoiceView.onSelectedListener; public class MainActivity extends Activity { private PopupWindow stationSelectDialog; private EditText edtView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); edtView = (EditText) findViewById(R.id.text); } public void OnViewClick(View v){ showMutiChoiceDialog(new String[]{"选项一","选项二","选项三","选项四","选项五","选项六","选项七","选项八","选项九","选项十",}, edtView); } private void showMutiChoiceDialog(final String[] stationsMean, final TextView textView){ if(stationSelectDialog == null){ LayoutInflater inflater = LayoutInflater.from(this); View view = inflater.inflate(R.layout.dialog_multiplechoice, null); CustomMultipleChoiceView mutipleChoiceView = (CustomMultipleChoiceView) view.findViewById(R.id.CustomMultipleChoiceView); mutipleChoiceView.setData(stationsMean, null); mutipleChoiceView.selectAll(); mutipleChoiceView.setTitle("多选"); stationSelectDialog = new PopupWindow(view, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, true); mutipleChoiceView.setOnSelectedListener(new onSelectedListener() { @Override public void onSelected(SparseBooleanArray sparseBooleanArray) { stationSelectDialog.dismiss(); StringBuilder sb = new StringBuilder(); for(int i=0; i<sparseBooleanArray.size(); i++){ if(sparseBooleanArray.get(i)){ sb.append(stationsMean[i] + ","); } } if(sb.length() > 0) sb.deleteCharAt(sb.length()-1); textView.setText(sb.toString()); } }); } stationSelectDialog.showAtLocation(getCurrentFocus(), Gravity.CENTER, 0, 0); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }
Ok,就是这么简单。
完整代码下载:例子
文章出自点击打开链接转载请注明出处。