Android微调多select

如何创build允许select多个项目的微调,即微调与checkbox?

我已经编写了MultiSpinner的自定义实现。 它看起来类似于正常的微调,但它有checkbox,而不是单选button。 选定的值显示在微调器上,并用逗号分隔。 所有的值都是默认选中的。 尝试一下:

 package cz.destil.settleup.gui; public class MultiSpinner extends Spinner implements OnMultiChoiceClickListener, OnCancelListener { private List<String> items; private boolean[] selected; private String defaultText; private MultiSpinnerListener listener; public MultiSpinner(Context context) { super(context); } public MultiSpinner(Context arg0, AttributeSet arg1) { super(arg0, arg1); } public MultiSpinner(Context arg0, AttributeSet arg1, int arg2) { super(arg0, arg1, arg2); } @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { if (isChecked) selected[which] = true; else selected[which] = false; } @Override public void onCancel(DialogInterface dialog) { // refresh text on spinner StringBuffer spinnerBuffer = new StringBuffer(); boolean someUnselected = false; for (int i = 0; i < items.size(); i++) { if (selected[i] == true) { spinnerBuffer.append(items.get(i)); spinnerBuffer.append(", "); } else { someUnselected = true; } } String spinnerText; if (someUnselected) { spinnerText = spinnerBuffer.toString(); if (spinnerText.length() > 2) spinnerText = spinnerText.substring(0, spinnerText.length() - 2); } else { spinnerText = defaultText; } ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, new String[] { spinnerText }); setAdapter(adapter); listener.onItemsSelected(selected); } @Override public boolean performClick() { AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setMultiChoiceItems( items.toArray(new CharSequence[items.size()]), selected, this); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); builder.setOnCancelListener(this); builder.show(); return true; } public void setItems(List<String> items, String allText, MultiSpinnerListener listener) { this.items = items; this.defaultText = allText; this.listener = listener; // all selected by default selected = new boolean[items.size()]; for (int i = 0; i < selected.length; i++) selected[i] = true; // all text on the spinner ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, new String[] { allText }); setAdapter(adapter); } public interface MultiSpinnerListener { public void onItemsSelected(boolean[] selected); } } 

你用这样的XML来使用它:

 <cz.destil.settleup.gui.MultiSpinner android:id="@+id/multi_spinner" /> 

你用Java把数据传给它:

 MultiSpinner multiSpinner = (MultiSpinner) findViewById(R.id.multi_spinner); multiSpinner.setItems(items, getString(R.string.for_all), this); 

你也需要实现监听器,它将返回相同长度的数组,用true或false来显示选中的未选中的..

 public void onItemsSelected(boolean[] selected); 

我只想展示@ Destil的MultiSpinner的另一个版本(谢谢你的鼓舞人心的代码),它允许在xml中使用“android:entries”,就像一个微调。

它最初不会显示默认文本,比如“select一个”,但是您可以通过在构造函数中设置额外的ArrayAdapter来轻松获取它。

MultiSpinner.java

 package com.example.helloworld; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnMultiChoiceClickListener; import android.content.res.TypedArray; import android.util.AttributeSet; import android.widget.ArrayAdapter; import android.widget.Spinner; /** * Inspired by: http://stackoverflow.com/a/6022474/1521064 */ public class MultiSpinner extends Spinner { private CharSequence[] entries; private boolean[] selected; private MultiSpinnerListener listener; public MultiSpinner(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MultiSpinner); entries = a.getTextArray(R.styleable.MultiSpinner_android_entries); if (entries != null) { selected = new boolean[entries.length]; // false-filled by default } a.recycle(); } private OnMultiChoiceClickListener mOnMultiChoiceClickListener = new OnMultiChoiceClickListener() { @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { selected[which] = isChecked; } }; private DialogInterface.OnClickListener mOnClickListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // build new spinner text & delimiter management StringBuffer spinnerBuffer = new StringBuffer(); for (int i = 0; i < entries.length; i++) { if (selected[i]) { spinnerBuffer.append(entries[i]); spinnerBuffer.append(", "); } } // Remove trailing comma if (spinnerBuffer.length() > 2) { spinnerBuffer.setLength(spinnerBuffer.length() - 2); } // display new text ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, new String[] { spinnerBuffer.toString() }); setAdapter(adapter); if (listener != null) { listener.onItemsSelected(selected); } // hide dialog dialog.dismiss(); } }; @Override public boolean performClick() { new AlertDialog.Builder(getContext()) .setMultiChoiceItems(entries, selected, mOnMultiChoiceClickListener) .setPositiveButton(android.R.string.ok, mOnClickListener) .show(); return true; } public void setMultiSpinnerListener(MultiSpinnerListener listener) { this.listener = listener; } public interface MultiSpinnerListener { public void onItemsSelected(boolean[] selected); } } 

attrs.xml

 <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MultiSpinner"> <attr name="android:entries" /> </declare-styleable> </resources> 

layout_main_activity.xml

 <com.example.helloworld.MultiSpinner android:id="@+id/multispinner" android:layout_width="match_parent" android:layout_height="wrap_content" android:entries="@array/multispinner_entries" /> 

就我所知, Spinner并没有多重select模式。 相反,您可以创build一个ImageButton并在右侧设置一个可绘制的向下箭头,在点击事件中,您可以打开一个包含多个checkbox项目的Dialog

请参阅这里: Android多选对话框

感谢您的post! 好的解决scheme 我对类进行了一些小改动(方法setItems),以允许用户设置已经select的项目,而不是默认select全部项目为true。

 public void setItems( List<String> items, List<String> itemValues, String selectedList, String allText, MultiSpinnerListener listener) { this.items = items; this.defaultText = allText; this.listener = listener; String spinnerText = allText; // Set false by default selected = new boolean[itemValues.size()]; for (int j = 0; j < itemValues.size(); j++) selected[j] = false; if (selectedList != null) { spinnerText = ""; // Extract selected items String[] selectedItems = selectedList.trim().split(","); // Set selected items to true for (int i = 0; i < selectedItems.length; i++) for (int j = 0; j < itemValues.size(); j++) if (selectedItems[i].trim().equals(itemValues.get(j))) { selected[j] = true; spinnerText += (spinnerText.equals("")?"":", ") + items.get(j); break; } } // Text for the spinner ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item, new String[] { spinnerText }); setAdapter(adapter); }