Spinner with checkbox items, is it possible?

前端 未结 6 1180
南笙
南笙 2020-12-06 06:48

Spinner with checkbox items, is it possible?

相关标签:
6条回答
  • 2020-12-06 07:08

    You can use the 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:

    <xxx.xx.gui.MultiSpinner android:id="@+id/SpinnerCollegues"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" 
        android:prompt="@string/university"/>
    
    0 讨论(0)
  • 2020-12-06 07:08

    There is implemented a MultiSpinner, you can find it on AndroidArsenal

    Can find it on Maven Repository

    If you add a hint to it, looks nice: android:hint="Choose ..."

    0 讨论(0)
  • 2020-12-06 07:19

    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 :-)

            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.

    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

    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.

            <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.

    @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));
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-06 07:25

    You could just create a ListView with check boxes. You could even add it to a dialog. That's essentially all a spinner is.

    0 讨论(0)
  • 2020-12-06 07:32

    Try this

     <selva.spinner.multispinner android:id="@+id/multi_spinner" 
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    

    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

     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);
          }
    
     }
    
    0 讨论(0)
  • 2020-12-06 07:33

    That depends on what you mean.

    If you want a true multi-select Spinner, then there's nothing built into Android for that.

    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.

    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.

    0 讨论(0)
提交回复
热议问题