Android Dialog实现全选反选

        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{

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

最后,是主界面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;
	@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,就是这么简单。

完整代码下载:例子

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

你可能感兴趣的:(android,对话框)