Spinner avec des éléments de case à cocher, est-ce possible?Spinner avec des cases à cocher, est-ce possible?
Répondre
Cela dépend de ce que vous voulez dire.
Si vous voulez un véritable multi-select Spinner
, alors il n'y a rien de construit dans Android pour cela.
Notez que vous avez le contrôle sur ce qui se passe dans les lignes Spinner
de la liste déroulante, à l'exception du bouton radio. Si vous voulez mettre des cases à cocher dans vos lignes, soyez mon invité. Cela semblera étrange, peut ne pas fonctionner correctement en ce qui concerne les événements tactiles, ne supprimera pas les boutons radio (AFAIK), et sera complètement sans rapport avec le contenu du Spinner
en mode normal. Par conséquent, je ne peux pas recommander cette approche, mais c'est faisable.
Le code source à Spinner
est disponible à partir du projet open source Android, donc vous êtes invités à le cloner et développer un MultiSelectSpinner
ou quelque chose.
Vous pouvez simplement créer une ListView avec des cases à cocher. Vous pourriez même l'ajouter à une boîte de dialogue. C'est essentiellement tout ce qu'un spinner est.
Bonne idée! Merci! –
Vous pouvez utiliser le 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);
}
}
Et puis dans votre mise en page .xml:
<xxx.xx.gui.MultiSpinner android:id="@+id/SpinnerCollegues"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:prompt="@string/university"/>
Essayez cette
<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);
}
}
J'ai créé une dynamique remplie Spinner qui obtient son contenu sur la requête de base de données SQLite sur le résolveur de contenu, il est une image au lieu de texte quand il est fermé, il montre ce qui est sélectionné , et son génial :-) 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);
}
maintenant, il ressemble à un simple, Spinner, ce qui en fait montrer sa sélection est cette ligne, il remplira les valeurs et mettre un radioCheckbox sur le côté droit, le haut/1er L'élément de votre liste sera présélectionné.
adapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
il y a plusieurs autres mises en page prédéfinies Wich travail assez bien
- simple_list_item_checked -> montre un Checkmark au lieu d'un RadioButton
- simple_list_item_activated_1 ou 2 -> Modifications BackgroundColor
- simple_list_item_multiple_choice - > CheckBoxes avec checkMarks
pour compléter ici est ma mise en page, il montre une image marquée ou non marquée (et non ce qui est sélectionné) donc j'ai spécifié R.layout.ghost_text dans le 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" />
ici mon onItemSelecte qui a besoin des Interfaces OnItemSelectedListener. Ce qu'il fait, il garde une trace avec un booléen si c'est l'initialisation du spinner ou non. S'il y a un vrai clic, nous extrayons l'information et mettons à jour un autre élément d'IU sur un contrôleur (peut aussi être un rappel) si l'élément cliqué est l'élément StandardSélectionné je place le SpinnerImage non sélectionné, si c'est autre que l'élément standard le spinnerImage sélectionné.
@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));
}
}
}
Il est mis en œuvre un MultiSpinner, vous pouvez le trouver sur AndroidArsenal
peut trouver sur Maven Repository
Si vous ajoutez un soupçon à elle, semble bien: android: indice = "Choisissez ... "
Merci! Il semble que ce soit trop de problèmes, peut-être que je vais utiliser une autre approche. –