Jak mogę pokazać Combobox w Androidzie? [Zamknięte]

80

Jak mogę pokazać Combobox w Androidzie?

James
źródło
1
Wyjaśnij wyraźniej, czego chcesz. A czego już próbowałeś.
fretje
30
@fretje Pytanie jest dość konkretne. Jeśli wiesz, czym jest ComboBox , nie potrzebujesz żadnych wyjaśnień. Jeśli nie, nadal możesz go
wygooglować
1
@vbence: Nie mówiłem o ComboBox. Ponieważ Android jest systemem operacyjnym, równie dobrze można zapytać „Jak wyświetlić pole wyboru w systemie Windows”, co wcale nie jest specyficzne.
fretje
18
@fretje Dla Windows nie byłoby to wystarczająco szczegółowe z oczywistych powodów (możesz to zrobić w C # lub Delphi itp.), ale na Androidzie mówisz o jednym frameworku programistycznym. Kiedy mówisz o Androidzie, jest to tak samo konkretne, jak powiedzenie Visual Basic .Net .
vbence
wypróbuj ten przykład stackoverflow.com/a/17650125/2027232
Nicolas Tyler

Odpowiedzi:

76

W Androidzie nazywa się Spinner, możesz rzucić okiem na samouczek tutaj.

Witaj, Prządko

I to jest bardzo niejasne pytanie, powinieneś spróbować bardziej opisać swój problem.

chrząknął
źródło
17
Proponuję rozważyć to w kontekście rozwoju Androida. designerandroid.com/?p=8 . W kontekście android dev jest określany jako Spinner. Następnym razem zbierz informacje.
chrząknął
3
Tak i patrząc na witrynę, którą sobie podałeś, możesz zobaczyć, że wspominają o ComboBox na tej stronie, ale w API jest tylko odniesienie do Spinner ( developer.android.com/resources/tutorials/views/ ... ) Tutaj wyraźnie stwierdzają, że „Spinner jest widżetem podobnym do rozwijanej listy do wybierania elementów”. Zgadzam się z Tobą, że POWINIEN to nazywać się ComboBox, tak jak w przypadku innych implementacji Java, ale w tym kontekście tak nie jest.
chrząknął
3
Rozumiem, że metafora trochę się zmienia w przypadku mobilnych interfejsów użytkownika. Istnieją nowe widżety (kontrolki), które mogą lepiej wykorzystać ograniczoną przestrzeń ekranu. Myślę, że dlatego użyłem nowych nazw niektórych kontrolek, które są znane z metafory pulpitu. - Zgadzam się, że Spinner jest podobny do rozwijanej listy. Jednak główna różnica między ListBox (lista rozwijana) a ComboBox polega na tym, że pole kombi jest w zasadzie polem wprowadzania tekstu rozszerzonym o możliwość wyboru z listy. Możesz wybrać element z listy lub wprowadzić dowolne wartości.
vbence
15
Przestań szukać dziurawego dzioba i przyznaj, że każdy miał problem ze znalezieniem kontrolki, która działa jak pole kombi lub pole listy, gdy pierwszy raz pisali aplikację na Androida ...
Torp
11
Nadal szukam pola kombi ... Widziałem Spinners. Używane błystki. Ale szczerze mówiąc mam scenariusz, w którym muszę ustawić tekst na coś innego niż dana opcja. Aka, mogą to wpisać. Spinners nie są polami kombi, ale zwykle są dobrą alternatywą.
IAmGroot
11

Oto przykład niestandardowego combobox w systemie Android:

package myWidgets;
import android.content.Context;
import android.database.Cursor;
import android.text.InputType;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.SimpleCursorAdapter;

public class ComboBox extends LinearLayout {

   private AutoCompleteTextView _text;
   private ImageButton _button;

   public ComboBox(Context context) {
       super(context);
       this.createChildControls(context);
   }

   public ComboBox(Context context, AttributeSet attrs) {
       super(context, attrs);
       this.createChildControls(context);
}

 private void createChildControls(Context context) {
    this.setOrientation(HORIZONTAL);
    this.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
                   LayoutParams.WRAP_CONTENT));

   _text = new AutoCompleteTextView(context);
   _text.setSingleLine();
   _text.setInputType(InputType.TYPE_CLASS_TEXT
                   | InputType.TYPE_TEXT_VARIATION_NORMAL
                   | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
                   | InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE
                   | InputType.TYPE_TEXT_FLAG_AUTO_CORRECT);
   _text.setRawInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD);
   this.addView(_text, new LayoutParams(LayoutParams.WRAP_CONTENT,
                   LayoutParams.WRAP_CONTENT, 1));

   _button = new ImageButton(context);
   _button.setImageResource(android.R.drawable.arrow_down_float);
   _button.setOnClickListener(new OnClickListener() {
           @Override
           public void onClick(View v) {
                   _text.showDropDown();
           }
   });
   this.addView(_button, new LayoutParams(LayoutParams.WRAP_CONTENT,
                   LayoutParams.WRAP_CONTENT));
 }

/**
    * Sets the source for DDLB suggestions.
    * Cursor MUST be managed by supplier!!
    * @param source Source of suggestions.
    * @param column Which column from source to show.
    */
 public void setSuggestionSource(Cursor source, String column) {
    String[] from = new String[] { column };
    int[] to = new int[] { android.R.id.text1 };
    SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this.getContext(),
                   android.R.layout.simple_dropdown_item_1line, source, from, to);
    // this is to ensure that when suggestion is selected
    // it provides the value to the textbox
    cursorAdapter.setStringConversionColumn(source.getColumnIndex(column));
    _text.setAdapter(cursorAdapter);
 }

/**
    * Gets the text in the combo box.
    *
    * @return Text.
    */
public String getText() {
    return _text.getText().toString();
 }

/**
    * Sets the text in combo box.
    */
public void setText(String text) {
    _text.setText(text);
   }
}

Mam nadzieję, że to pomoże!!

Raneez Ahmed
źródło
1
Dziękuję za odpowiedź. Chcę użyć tego widżetu, ale chcę użyć tablicy String jako źródła danych, a nie kursora. co powinienem zrobić?
Ali Behzadian Nejad
7

Nie testowane, ale wydaje się, że im bliżej możesz być, jest z AutoCompleteTextView . Można napisać adapter, który ignoruje funkcje filtrujące. Coś jak:

class UnconditionalArrayAdapter<T> extends ArrayAdapter<T> {
    final List<T> items;
    public UnconditionalArrayAdapter(Context context, int textViewResourceId, List<T> items) {
        super(context, textViewResourceId, items);
        this.items = items;
    }

    public Filter getFilter() {
        return new NullFilter();
    }

    class NullFilter extends Filter {
        protected Filter.FilterResults performFiltering(CharSequence constraint) {
            final FilterResults results = new FilterResults();
            results.values = items;
            return results;
        }

        protected void publishResults(CharSequence constraint, Filter.FilterResults results) {
            items.clear(); // `items` must be final, thus we need to copy the elements by hand.
            for (Object item : (List) results.values) {
                items.add((String) item);
            }
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    }
}

... potem w swoim onCreate:

String[] COUNTRIES = new String[] {"Belgium", "France", "Italy", "Germany"};
List<String> contriesList = Arrays.asList(COUNTRIES());
ArrayAdapter<String> adapter = new UnconditionalArrayAdapter<String>(this,
    android.R.layout.simple_dropdown_item_1line, contriesList);
AutoCompleteTextView textView = (AutoCompleteTextView)
    findViewById(R.id.countries_list);
textView.setAdapter(adapter);

Kod nie jest testowany, mogą istnieć pewne funkcje z metodą filtrowania, której nie brałem pod uwagę, ale oto masz podstawowe zasady emulacji ComboBox z AutoCompleteTextView.

Edytuj implementację Fixed NullFilter. Potrzebujemy dostępu do elementów, dlatego konstruktor UnconditionalArrayAdaptermusi pobrać odniesienie do listy (rodzaj bufora). Możesz także użyć np. adapter = new UnconditionalArrayAdapter<String>(..., new ArrayList<String>);A następnie użyć adapter.add("Luxemburg"), więc nie musisz zarządzać listą buforów.

vbence
źródło
Ten kod nie jest bliski kompilacji. Wywołania metody getFilter () wyglądają jak próby wykonania nieskończonej pętli, a publikacjaResults zwraca wartość z metody void. Pomysł jest ogólnie dobry, ale ktoś powinien naprawić ten przykład.
dhakim
6

Pytania są całkowicie poprawne i jasne, ponieważ Spinner i ComboBox (czytaj: Spinner, w którym można również podać niestandardową wartość) to dwie różne rzeczy.

Sam szukałem tego samego i nie byłem zadowolony z udzielonych odpowiedzi. Więc stworzyłem własną rzecz. Być może dla niektórych przydatne będą poniższe wskazówki. Nie dostarczam pełnego kodu źródłowego, ponieważ używam niektórych starszych wywołań w moim własnym projekcie. I tak powinno być całkiem jasne.

Oto zrzut ekranu ostatniej rzeczy:

ComboBox na Androida

Pierwszą rzeczą było stworzenie widoku, który będzie wyglądał tak samo, jak nie rozwinięty jeszcze spinner. Na zrzucie ekranu w górnej części ekranu (nieostre) widać pokrętło, a poniżej znajduje się niestandardowy widok. W tym celu użyłem LinearLayout (właściwie odziedziczyłem po Linear Layout) z style="?android:attr/spinnerStyle". LinearLayout zawiera TextView z style="?android:attr/spinnerItemStyle". Pełny fragment kodu XML wyglądałby tak:

<com.example.comboboxtest.ComboBox 
    style="?android:attr/spinnerStyle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >

    <TextView
        android:id="@+id/textView"
        style="?android:attr/spinnerItemStyle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ellipsize="marquee"
        android:singleLine="true"
        android:text="January"
        android:textAlignment="inherit" 
    />

</com.example.comboboxtest.ComboBox>

Jak wspomniałem wcześniej ComboBox dziedziczy po LinearLayout. Implementuje również OnClickListener, który tworzy okno dialogowe z niestandardowym widokiem zawyżonym z pliku XML. Oto zawyżony widok:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" 
    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" 
        >
        <EditText
            android:id="@+id/editText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ems="10"
            android:hint="Enter custom value ..." >

            <requestFocus />
        </EditText>

        <Button
            android:id="@+id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="OK" 
        />
    </LinearLayout>

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
    />

</LinearLayout>

Są jeszcze dwa detektory, które musisz zaimplementować: onItemClick dla listy i onClick dla przycisku. Oba ustawiają wybraną wartość i zamykają okno dialogowe.

Jeśli chodzi o listę, chcesz, aby wyglądała tak samo jak rozwinięty Spinner, możesz to zrobić, dostarczając adapterowi listy odpowiedni styl (Spinner) w następujący sposób:

ArrayAdapter<String> adapter = 
    new ArrayAdapter<String>(
        activity,
        android.R.layout.simple_spinner_dropdown_item, 
        states
    );

Mniej więcej tak powinno być.

Viktor Brešan
źródło
Wygląda dobrze. Próbuję wdrożyć Twoje rozwiązanie, ale jestem nowy w programowaniu dla Androida i jestem trochę zdezorientowany, gdzie umieścić fragmenty. Czy mógłbyś trochę powtórzyć, aby wyjaśnić, jak to wdrożyć?
You'reAGitForNotUsingGit
4

Wykonane na zamówienie :) możesz użyć rozwijanych właściwości przesunięcia poziomego / pionowego, aby ustawić bieżącą listę, spróbuj także android: spinnerMode = "dialog", jest chłodniej.

Układ

  <LinearLayout
        android:layout_marginBottom="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <AutoCompleteTextView
            android:layout_weight="1"
            android:id="@+id/edit_ip"
            android:text="default value"
            android:layout_width="0dp"
            android:layout_height= "wrap_content"/>
        <Spinner
            android:layout_marginRight="20dp"
            android:layout_width="30dp"
            android:layout_height="50dp"
            android:id="@+id/spinner_ip"
            android:spinnerMode="dropdown"
            android:entries="@array/myarray"/>
 </LinearLayout>

Jawa

          //set auto complete
        final AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.edit_ip);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, getResources().getStringArray(R.array.myarray));
        textView.setAdapter(adapter);
        //set spinner
        final Spinner spinner = (Spinner) findViewById(R.id.spinner_ip);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                textView.setText(spinner.getSelectedItem().toString());
                textView.dismissDropDown();
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                textView.setText(spinner.getSelectedItem().toString());
                textView.dismissDropDown();
            }
        });

res / values ​​/ string

<string-array name="myarray">
    <item>value1</item>
    <item>value2</item>
</string-array>

Czy to było przydatne?

ShAkKiR
źródło
jak twoja odpowiedź gdzie kliknij AutoCompleteTextView i pokaż?
ZarNi Myo Sett Wygraj
możesz dodać dodatkowe zdarzenia do AutoCompleteTextView lub pokrętła, jak chcesz.
ShAkKiR
0

W przypadku combobox ( http://en.wikipedia.org/wiki/Combo_box ), który pozwala na dowolne wprowadzanie tekstu i ma rozwijaną listę, użyłem AutoCompleteTextViewzgodnie z sugestią vbence.

Użyłem onClickListenerdo wyświetlenia pola listy rozwijanej, gdy użytkownik wybierze formant.

Uważam, że to najlepiej przypomina ten rodzaj combobox.

private static final String[] STUFF = new String[] { "Thing 1", "Thing 2" };

public void onCreate(Bundle b) {
    final AutoCompleteTextView view = 
        (AutoCompleteTextView) findViewById(R.id.myAutoCompleteTextView);

    view.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
                view.showDropDown();
        }
    });

    final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
        this, 
        android.R.layout.simple_dropdown_item_1line,
        STUFF
    );
    view.setAdapter(adapter);
}
rve
źródło