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


80

Jak mogę pokazać Combobox w Androidzie?


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

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.


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


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.


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


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?


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);
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.