Android Dialog实现全选反选
16lz
2021-01-23
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>
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,就是这么简单。
完整代码下载:例子
文章出自点击打开链接转载请注明出处。
更多相关文章
- android 布局文件中控件ID、name标签属性的命名包含“@”、“.”
- android延迟执行任务(刷新按钮旋转)
- 【源码分享下载】每日更新之Android应用源码之仿微信5.2布局
- Android控件-多选按钮、单选按钮
- Android之基本样式和布局
- android -------- 流式布局,支持单选、多选等
- 约束布局ConstraintLayout的使用你知道吗