Android 带有复选框项目的微调器,可能吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2682582/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spinner with checkbox items, is it possible?
提问by Jan S.
Spinner with checkbox items, is it possible?
带有复选框项目的微调器,可能吗?
采纳答案by CommonsWare
That depends on what you mean.
这取决于你的意思。
If you want a true multi-select Spinner
, then there's nothing built into Android for that.
如果你想要一个真正的 multi-select Spinner
,那么 Android 没有内置任何东西。
Note that you are in control over what goes in the Spinner
rows of the drop-down list, except for the radio button. If you want to put checkboxes in your rows, be my guest. It'll look strange, may not work properly with respect to touch events, will not remove the radio buttons (AFAIK), and will be completely unrelated to the Spinner
's contents in normal mode. Hence, I can't recommend this approach, but it is doable.
请注意,您可以控制Spinner
下拉列表行中的内容,单选按钮除外。如果您想在行中放置复选框,请成为我的客人。它看起来很奇怪,可能无法在触摸事件方面正常工作,不会删除单选按钮(AFAIK),并且与Spinner
正常模式下的内容完全无关。因此,我不能推荐这种方法,但它是可行的。
The source code to Spinner
is available from the Android open source project, so you are welcome to clone it and develop a MultiSelectSpinner
or something.
to的源代码Spinner
来自Android开源项目,欢迎大家克隆开发MultiSelectSpinner
什么的。
回答by selva_pollachi
Try this
尝试这个
<selva.spinner.multispinner android:id="@+id/multi_spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
Spinner1Activity.java
Spinner1Activity.java
package selva.spinner;
import java.util.ArrayList;
import java.util.List;
import selva.spinner.multispinner.multispinnerListener;
import android.app.Activity;
import android.os.Bundle;
public class Spinner1Activity extends Activity implements multispinnerListener
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
multispinner ms = (multispinner) findViewById(R.id.multi_spinner);
List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
list.add("five");
list.add("six");
list.add("seven");
list.add("eight");
list.add("nine");
list.add("ten");
ms.setItems(list, "select", this);
}
@Override
public void onItemschecked(boolean[] checked)
{
// TODO Auto-generated method stub
}
}
multispinner.java
多微调器.java
package selva.spinner;
import java.util.List;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.util.AttributeSet;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
public class multispinner extends Spinner implements
OnMultiChoiceClickListener, OnCancelListener
{
private List<String> listitems;
private boolean[] checked;
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 ans, boolean isChecked)
{
if (isChecked)
checked[ans] = true;
else
checked[ans] = false;
}
@Override
public void onCancel(DialogInterface dialog)
{
String str="Selected values are: ";
for (int i = 0; i < listitems.size(); i++)
{
if (checked[i] == true)
{
str=str+" "+listitems.get(i);
}
}
AlertDialog.Builder alert1 = new AlertDialog.Builder(getContext());
alert1.setTitle("Items:");
alert1.setMessage(str);
alert1.setPositiveButton("Ok", null);
alert1.show();
}
@Override
public boolean performClick()
{
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setMultiChoiceItems(
listitems.toArray(new CharSequence[listitems.size()]), checked, this);
builder.setPositiveButton("done",
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.listitems = items;
checked = new boolean[items.size()];
for (int i = 0; i < checked.length; i++)
checked[i] =false;
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),
android.R.layout.simple_spinner_item, new String[] { allText });
setAdapter(adapter);
}
public interface multispinnerListener
{
public void onItemschecked(boolean[] checked);
}
}
回答by chemalarrea
You can use the multiSpinner:
您可以使用 multiSpinner:
import java.util.List;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnMultiChoiceClickListener;
import android.util.AttributeSet;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
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(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);
}
}
}
And then in your layout .xml:
然后在您的布局 .xml 中:
<xxx.xx.gui.MultiSpinner android:id="@+id/SpinnerCollegues"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:prompt="@string/university"/>
回答by Arnold Vakaria
There is implemented a MultiSpinner, you can find it on AndroidArsenal
实现了MultiSpinner,您可以在 AndroidArsenal 上找到它
Can find it on Maven Repository
可以在Maven Repository上找到它
If you add a hint to it, looks nice: android:hint="Choose ..."
如果你添加一个提示,看起来不错: android:hint="Choose ..."
回答by Jay Askren
You could just create a ListView with check boxes. You could even add it to a dialog. That's essentially all a spinner is.
您可以创建一个带有复选框的 ListView。您甚至可以将其添加到对话框中。这基本上就是一个微调器。
回答by swisscoder
I created a dynamic filled Spinner which gets its content over the Sqlite Database query over the content resolver, it's a Image instead of text when closed, it shows whats selected, and its awesome simple :-)
我创建了一个动态填充的 Spinner,它通过内容解析器的 Sqlite 数据库查询获取其内容,关闭时它是图像而不是文本,它显示选择的内容,并且非常简单:-)
spinnerFavorites = (SpinnerMultiSameClick) v.findViewById(R.id.guide_btn_favorites);
spinnerFavorites.setOnItemSelectedListener(this);
ContentResolver resolver = activity.getContentResolver();
String[] projection = new String[] { DataContract.Favorites.FAVORITES_ID, DataContract.Favorites.NAME };
Cursor cursor = resolver.query(DataContract.Favorites.CONTENT_URI, projection, null, null, DataContract.Favorites.FAVORITES_ID +" ASC");
if (cursor.getCount() > 0) {
// create an array to specify which fields we want to display
String[] from = new String[] { DataContract.Favorites.NAME, DataContract.Favorites.FAVORITES_ID };
// create an array of the display item we want to bind our data
// to
int[] to = new int[] { android.R.id.text1, android.R.id.text2 };
SimpleCursorAdapter adapter = new SimpleCursorAdapter(activity, R.layout.ghost_text, cursor, from, to,
SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
// get reference to our spinner
spinner.setAdapter(adapter);
adapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
} else {
// TODO: Maybe button to make new favList
spinnerFavorites.setVisiblity(View.GONE);
}
Now, it looks like a simple Spinner, what makes it show its selection is this line, it will fill the values and put a radioCheckbox on the right side, the top/1st Element in your list will be preselected.
现在,它看起来像一个简单的 Spinner,它显示其选择的是这一行,它将填充值并在右侧放置一个 radioCheckbox,您列表中的顶部/第一个元素将被预选。
adapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
there are several other predefined layouts wich work pretty well
还有其他几种预定义的布局效果很好
- simple_list_item_checked -> shows a checkMark instead of a RadioButton
- simple_list_item_activated_1 or 2 -> Changes BackgroundColor
- simple_list_item_multiple_choice -> CheckBoxes with checkMarks
- simple_list_item_checked -> 显示一个复选标记而不是一个 RadioButton
- simple_list_item_activated_1 或 2 -> 更改背景颜色
- simple_list_item_multiple_choice -> 带有复选标记的复选框
to complete here is my layout, it shows an marked or unmarked Image (and not whats selected) therefore i specified R.layout.ghost_text in the spinnerAdapter.
这里要完成的是我的布局,它显示了一个标记或未标记的图像(而不是选择了什么),因此我在 spinnerAdapter 中指定了 R.layout.ghost_text。
<com.netstream.ch.tv.android.ui.program.guide.land.SpinnerMultiSameClick
android:id="@+id/guide_btn_favorites"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:background="@drawable/icon_selector_guide_filter_favorites"
android:clickable="true" />
here my onItemSelecte which needs the OnItemSelectedListener Interfaces. What it does, it keeps track with a boolean if its the initialisation of the spinner or not. If there is a real click, we extract the information and update another UI Element over a Controller (could also be a callback) if the Clicked Element is the StandardSelected Element i set the SpinnerImage unselected, if its sth else then the standard element i set the spinnerImage selected.
这里我的 onItemSelecte 需要 OnItemSelectedListener 接口。它的作用是,它跟踪一个布尔值是否是微调器的初始化。如果有真正的点击,我们提取信息并更新控制器上的另一个 UI 元素(也可以是回调)如果被点击的元素是 StandardSelected 元素,我将 SpinnerImage 设置为未选择,如果是其他,则我设置的标准元素选择的 spinnerImage。
@Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (parent.getId() == R.id.guide_btn_favorites) {
if (!AbsintheViewControllerFactory.getGuideController().isFavoriteListInitialisation()) {
Cursor c = (Cursor) parent.getItemAtPosition(pos);
String favid = c.getString(c.getColumnIndexOrThrow(DataContract.Favorites.FAVORITES_ID));
String name = c.getString(c.getColumnIndexOrThrow(DataContract.Favorites.NAME));
Log.d(TAG, "Set Filter to FavListId: " + favid + " by its name: " + name);
if (favid.equalsIgnoreCase(GuideViewController.allChannelsFavoritesIdentifier)) {
spinnerFavorites.setSelected(false);
} else {
spinnerFavorites.setSelected(true);
}
AbsintheViewControllerFactory.getGuideController().setFavourites(favid);
guideInfoSelectedFavoriteList.setText(name);
} else {
AbsintheViewControllerFactory.getGuideController().setFavoriteListInitialisation(false);
guideInfoSelectedFavoriteList.setText(getActivity().getResources().getString(R.string.FILTER_FAVORITE_ALL_CHANNELS));
}
}
}