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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:55:52  来源:igfitidea点击:

Spinner with checkbox items, is it possible?

androidcheckboxspinner

提问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 Spinnerrows 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 Spinneris available from the Android open source project, so you are welcome to clone it and develop a MultiSelectSpinneror 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));
        }
    }
}