Android的AlertDialog中可以通过builder.setMultiChoiceItems(....)来添加一个多选项,但是并不能实现对选项的全选/反选功能,所以需要自定义一个控件。原理是通过ListView + CheckBox来实现,实现效果如下。

Android Dialog实现全选反选_第1张图片

一、定义布局样式:

首先需要定义多选弹出框的样式,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>

ListView条目的样式, custom_mutiplechoice_view_list_item.xml:

<?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> 

然后是定义弹出框的布局,dialog_multiplechoice.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: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>

Activity主界面的布局,activity_main.xml:

<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>

二、弹出框ListView是适配器,MutipleChoiceAdapter.java:

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;      }  }

多选对话框的自定义View,CustomMultipleChoiceView.java:

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{@Overridepublic 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;}}}}

最后,是主界面Activity的代码,MainActivity.java:

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;@Overrideprotected 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() {@Overridepublic 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);}@Overridepublic 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,就是这么简单。

完整代码下载:例子

文章出自点击打开链接转载请注明出处。

更多相关文章

  1. android 布局文件中控件ID、name标签属性的命名包含“@”、“.”
  2. android延迟执行任务(刷新按钮旋转)
  3. 【源码分享下载】每日更新之Android应用源码之仿微信5.2布局
  4. Android控件-多选按钮、单选按钮
  5. Android之基本样式和布局
  6. android -------- 流式布局,支持单选、多选等
  7. 约束布局ConstraintLayout的使用你知道吗

随机推荐

  1. Android(安卓)自定义View之展开收起的Lay
  2. 浅析Android下的Android.mk文件
  3. Android真机连接本地部署的Tomcat问题
  4. Android中ViewPager+Fragment取消(禁止)
  5. Android(安卓)外部存储与内部存储详解
  6. android mvvm viewmodel 拿到view的值_一
  7. Android事件分发机制五:面试官你坐啊
  8. Python爬虫 - 抓取divnil动漫妹子图
  9. Android(安卓)Wifi 2.4G 5G附近扫描查看
  10. Android的体系结构