Bagaimana cara mengatur item Spinner yang dipilih berdasarkan nilai, bukan berdasarkan posisi?

297

Saya memiliki tampilan pembaruan, di mana saya harus memilih dulu nilai yang disimpan dalam database untuk Spinner.

Saya sedang memikirkan sesuatu seperti ini, tetapi Adaptertidak memiliki indexOfmetode, jadi saya terjebak.

void setSpinner(String value)
{
    int pos = getSpinnerField().getAdapter().indexOf(value);
    getSpinnerField().setSelection(pos);
}
Pentium10
sumber

Jawaban:

646

Misalkan Spinnernama Anda mSpinner, dan itu berisi sebagai salah satu pilihannya: "beberapa nilai".

Untuk menemukan dan membandingkan posisi "beberapa nilai" di Spinner gunakan ini:

String compareValue = "some value";
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.select_state, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(adapter);
if (compareValue != null) {
    int spinnerPosition = adapter.getPosition(compareValue);
    mSpinner.setSelection(spinnerPosition);
}
Merrill
sumber
5
dengan adaptor khusus Anda harus menulis (menimpa) kode untuk getPosition ()
Soham
3
Bagaimana jika Anda tidak memeriksa string tetapi elemen di dalam objek dan tidak mungkin hanya menggunakan toString () karena nilai spinner bervariasi dari output toString ().
Ajibola
1
Saya tahu ini sudah sangat lama, tetapi ini sekarang melontarkan panggilan yang tidak dicentang ke getPosition (T)
Brad Bass
memiliki kesalahan serupa yang dilemparkan, tetapi menggunakan cara sekolah lama ini membantu: stackoverflow.com/questions/25632549/…
Manny265
Hmm ... Sekarang bagaimana jika saya menarik nilai dari, katakanlah, Parse.com, dan ingin meminta pengguna sehingga pilihan pemintal default default ke nilai basis data pengguna?
drearypanoramic
141

Cara sederhana untuk mengatur pemintal berdasarkan nilai adalah

mySpinner.setSelection(getIndex(mySpinner, myValue));

 //private method of your class
 private int getIndex(Spinner spinner, String myString){
     for (int i=0;i<spinner.getCount();i++){
         if (spinner.getItemAtPosition(i).toString().equalsIgnoreCase(myString)){
             return i;
         }
     }

     return 0;
 } 

Cara untuk kode kompleks sudah ada, ini lebih sederhana.

Akhil Jain
sumber
7
Anda lupa menambahkan break;ketika indeks ditemukan untuk mempercepat proses.
spacebiker
mengapa tidak menggunakan do {} while () untuk menghindari penggunaan break?
Catluc
@Catluc ada n sejumlah cara untuk sampai pada solusi, Anda memilih ... apa yang terbaik untuk Anda
Akhil Jain
4
Daripada 0, Anda harus kembali -1jika nilainya tidak ditemukan - seperti yang ditunjukkan dalam jawaban saya: stackoverflow.com/a/32377917/1617737 :-)
ban-geoengineering
2
@ larangan geoengineering saya tulis 0sebagai skenario cadangan. Jika Anda mengatur -1, item apa yang akan terlihat di spinner, saya kira elemen ke 0 dari spinner adapter, menambahkan -1 juga menambahkan kelebihan memeriksa apakah nilainya -1 atau tidak, karena pengaturan -1 akan menyebabkan pengecualian.
Akhil Jain
34

Saya menyimpan ArrayList terpisah dari semua item di Spinners saya. Dengan cara ini saya bisa melakukan indexOf di ArrayList dan kemudian menggunakan nilai itu untuk mengatur pilihan di Spinner.

Mark B
sumber
Tidak ada cara lain, Anda tahu?
Pentium10
1
Bagaimana cara mengatur pilihan ke nol? (jika item tidak ada dalam daftar)
Pentium10
5
HashMap.get akan memberikan kecepatan pencarian yang lebih baik daripada ArrayList.indexOf
Dandre Allison
29

Berdasarkan jawaban Merrill , saya datang dengan solusi garis tunggal ini ... tidak terlalu cantik, tetapi Anda dapat menyalahkan siapa pun yang memelihara kode Spinnerkarena mengabaikan menyertakan fungsi yang melakukan ini untuk itu.

mySpinner.setSelection(((ArrayAdapter<String>)mySpinner.getAdapter()).getPosition(myString));

Anda akan mendapatkan peringatan tentang bagaimana pemeran ke tanda ArrayAdapter<String>tidak dicentang ... sungguh, Anda bisa menggunakan ArrayAdapterseperti yang dilakukan Merrill, tetapi itu hanya bertukar satu peringatan dengan yang lainnya.

ArtOfWarfare
sumber
Untuk menghilangkan peringatan yang tidak dicentang, Anda harus menggunakan <? > di gips Anda, bukan <String>. Bahkan setiap kali Anda melemparkan sesuatu dengan tipe, Anda harus menggunakan <? >.
xbakesx
Tidak, jika saya memilih <? > itu memberi saya kesalahan alih-alih peringatan: "Metode getPosition (?) pada tipe ArrayAdapter <?> tidak berlaku untuk argumen (String)."
ArtOfWarfare
Benar, kemudian akan berpikir itu adalah ArrayAdapter tanpa tipe, jadi itu tidak akan menganggap itu ArrayAdapter <String>. Jadi, untuk menghindari peringatan, Anda harus membuangnya ke ArrayAdapter <? > lalu masukkan hasil adapter.get () ke sebuah String.
xbakesx
@Dadani - Saya rasa Anda tidak pernah menggunakan Python sebelumnya, karena ini berbelit-belit.
ArtOfWarfare
Setuju, saya belum bermain-main dengan Python @ArtOfWarfare, tapi ini cara cepat untuk tugas-tugas tertentu.
Daniel Dut
13

jika Anda menggunakan string array ini adalah cara terbaik:

int selectionPosition= adapter.getPosition("YOUR_VALUE");
spinner.setSelection(selectionPosition);
itzhar
sumber
10

Anda dapat menggunakan ini juga,

String[] baths = getResources().getStringArray(R.array.array_baths);
mSpnBaths.setSelection(Arrays.asList(baths).indexOf(value_here));
PrvN
sumber
Kerja Cemerlang!
Sadman Hasan
8

Jika Anda perlu memiliki metode indexOf pada Adaptor lama (dan Anda tidak tahu implementasi yang mendasarinya) maka Anda dapat menggunakan ini:

private int indexOf(final Adapter adapter, Object value)
{
    for (int index = 0, count = adapter.getCount(); index < count; ++index)
    {
        if (adapter.getItem(index).equals(value))
        {
            return index;
        }
    }
    return -1;
}
xbakesx
sumber
7

Berdasarkan jawaban Merrill di sini adalah bagaimana melakukan dengan CursorAdapter

CursorAdapter myAdapter = (CursorAdapter) spinner_listino.getAdapter(); //cast
    for(int i = 0; i < myAdapter.getCount(); i++)
    {
        if (myAdapter.getItemId(i) == ordine.getListino() )
        {
            this.spinner_listino.setSelection(i);
            break;
        }
    }
maksimal4ever
sumber
6

Gunakan baris berikut untuk memilih menggunakan nilai:

mSpinner.setSelection(yourList.indexOf("value"));
Faisal Shaikh
sumber
3

Saya menggunakan adaptor khusus, untuk itu kode ini cukup:

yourSpinner.setSelection(arrayAdapter.getPosition("Your Desired Text"));

Jadi, cuplikan kode Anda akan seperti ini:

void setSpinner(String value)
    {
         yourSpinner.setSelection(arrayAdapter.getPosition(value));
    }
Miral Sarwar
sumber
3

Ini adalah metode sederhana saya untuk mendapatkan indeks dengan string.

private int getIndexByString(Spinner spinner, String string) {
    int index = 0;

    for (int i = 0; i < spinner.getCount(); i++) {
        if (spinner.getItemAtPosition(i).toString().equalsIgnoreCase(string)) {
            index = i;
            break;
        }
    }
    return index;
}
aLIEz
sumber
3

Anda dapat menggunakan cara ini, cukup buat kode Anda lebih sederhana dan lebih jelas.

ArrayAdapter<String> adapter = (ArrayAdapter<String>) spinnerCountry.getAdapter();
int position = adapter.getPosition(obj.getCountry());
spinnerCountry.setSelection(position);

Semoga ini bisa membantu.

azwar_akbar
sumber
2

ini solusinya

List<Country> list = CountryBO.GetCountries(0);
CountriesAdapter dataAdapter = new CountriesAdapter(this,list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spnCountries.setAdapter(dataAdapter);
spnCountries.setSelection(dataAdapter.getItemIndexById(userProfile.GetCountryId()));

dan getItemIndexById di bawah ini

public int getItemIndexById(String id) {
    for (Country item : this.items) {
        if(item.GetId().toString().equals(id.toString())){
            return this.items.indexOf(item);
        }
    }
    return 0;
}

Semoga bantuan ini!

Scott.N
sumber
2

Berikut adalah cara melakukannya jika Anda menggunakan SimpleCursorAdapter(di mana columnNamenama kolom db yang Anda gunakan untuk mengisi spinner):

private int getIndex(Spinner spinner, String columnName, String searchString) {

    //Log.d(LOG_TAG, "getIndex(" + searchString + ")");

    if (searchString == null || spinner.getCount() == 0) {

        return -1; // Not found
    }
    else {

        Cursor cursor = (Cursor)spinner.getItemAtPosition(0);

        int initialCursorPos = cursor.getPosition(); //  Remember for later

        int index = -1; // Not found
        for (int i = 0; i < spinner.getCount(); i++) {

            cursor.moveToPosition(i);
            String itemText = cursor.getString(cursor.getColumnIndex(columnName));

            if (itemText.equals(searchString)) {
                index = i; // Found!
                break;
            }
        }

        cursor.moveToPosition(initialCursorPos); // Leave cursor as we found it.

        return index;
    }
}

Juga (penyempurnaan jawaban Akhil ) ini adalah cara yang sesuai untuk melakukannya jika Anda mengisi Spinner Anda dari sebuah array:

private int getIndex(Spinner spinner, String searchString) {

    if (searchString == null || spinner.getCount() == 0) {

        return -1; // Not found

    }
    else {

        for (int i = 0; i < spinner.getCount(); i++) {
            if (spinner.getItemAtPosition(i).toString().equals(searchString)) {
                return i; // Found!
            }
        }

        return -1; // Not found
    }
};
larangan geoengineering
sumber
1

Jika Anda mengatur array XML ke pemintal dalam tata letak XML Anda bisa melakukan ini

final Spinner hr = v.findViewById(R.id.chr);
final String[] hrs = getResources().getStringArray(R.array.hours);
if(myvalue!=null){
   for (int x = 0;x< hrs.length;x++){
      if(myvalue.equals(hrs[x])){
         hr.setSelection(x);
      }
   }
}
Lasitha Lakmal
sumber
0

Sebenarnya ada cara untuk mendapatkan ini menggunakan pencarian indeks pada AdapterArray dan semua ini dapat dilakukan dengan refleksi. Saya bahkan melangkah lebih jauh karena saya memiliki 10 Spinner dan ingin mengaturnya secara dinamis dari basis data saya dan basis data hanya menyimpan nilai bukan teks karena Spinner sebenarnya berubah dari minggu ke minggu sehingga nilainya adalah nomor id saya dari basis data.

 // Get the JSON object from db that was saved, 10 spinner values already selected by user
 JSONObject json = new JSONObject(string);
 JSONArray jsonArray = json.getJSONArray("answer");

 // get the current class that Spinner is called in 
 Class<? extends MyActivity> cls = this.getClass();

 // loop through all 10 spinners and set the values with reflection             
 for (int j=1; j< 11; j++) {
      JSONObject obj = jsonArray.getJSONObject(j-1);
      String movieid = obj.getString("id");

      // spinners variable names are s1,s2,s3...
      Field field = cls.getDeclaredField("s"+ j);

      // find the actual position of value in the list     
      int datapos = indexedExactSearch(Arrays.asList(Arrays.asList(this.data).toArray()), "value", movieid) ;
      // find the position in the array adapter
      int pos = this.adapter.getPosition(this.data[datapos]);

      // the position in the array adapter
      ((Spinner)field.get(this)).setSelection(pos);

}

Berikut ini adalah pencarian yang diindeks yang dapat Anda gunakan di hampir semua daftar selama bidang berada pada tingkat atas objek.

    /**
 * Searches for exact match of the specified class field (key) value within the specified list.
 * This uses a sequential search through each object in the list until a match is found or end
 * of the list reached.  It may be necessary to convert a list of specific objects into generics,
 * ie: LinkedList&ltDevice&gt needs to be passed as a List&ltObject&gt or Object[&nbsp] by using 
 * Arrays.asList(device.toArray(&nbsp)).
 * 
 * @param list - list of objects to search through
 * @param key - the class field containing the value
 * @param value - the value to search for
 * @return index of the list object with an exact match (-1 if not found)
 */
public static <T> int indexedExactSearch(List<Object> list, String key, String value) {
    int low = 0;
    int high = list.size()-1;
    int index = low;
    String val = "";

    while (index <= high) {
        try {
            //Field[] c = list.get(index).getClass().getDeclaredFields();
            val = cast(list.get(index).getClass().getDeclaredField(key).get(list.get(index)) , "NONE");
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        if (val.equalsIgnoreCase(value))
            return index; // key found

        index = index + 1;
    }

    return -(low + 1);  // key not found return -1
}

Metode pemeran yang dapat dibuat untuk semua primitif di sini adalah satu untuk string dan int.

        /**
 *  Base String cast, return the value or default
 * @param object - generic Object
 * @param defaultValue - default value to give if Object is null
 * @return - returns type String
 */
public static String cast(Object object, String defaultValue) {
    return (object!=null) ? object.toString() : defaultValue;
}


    /**
 *  Base integer cast, return the value or default
 * @param object - generic Object
 * @param defaultValue - default value to give if Object is null
 * @return - returns type integer
 */
public static int cast(Object object, int defaultValue) { 
    return castImpl(object, defaultValue).intValue();
}

    /**
 *  Base cast, return either the value or the default
 * @param object - generic Object
 * @param defaultValue - default value to give if Object is null
 * @return - returns type Object
 */
public static Object castImpl(Object object, Object defaultValue) {
    return object!=null ? object : defaultValue;
}
JPM
sumber
0

Untuk membuat aplikasi mengingat nilai pemintal yang terakhir dipilih, Anda dapat menggunakan kode di bawah ini:

  1. Kode di bawah ini membaca nilai pemintal dan mengatur posisi pemintal yang sesuai.

    public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    
    int spinnerPosition;
    
    Spinner spinner1 = (Spinner) findViewById(R.id.spinner1);
    ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource(
            this, R.array.ccy_array,
            android.R.layout.simple_spinner_dropdown_item);
    adapter1.setDropDownViewResource(android.R.layout.simple_list_item_activated_1);
    // Apply the adapter to the spinner
    spinner1.setAdapter(adapter1);
    // changes to remember last spinner position
    spinnerPosition = 0;
    String strpos1 = prfs.getString("SPINNER1_VALUE", "");
    if (strpos1 != null || !strpos1.equals(null) || !strpos1.equals("")) {
        strpos1 = prfs.getString("SPINNER1_VALUE", "");
        spinnerPosition = adapter1.getPosition(strpos1);
        spinner1.setSelection(spinnerPosition);
        spinnerPosition = 0;
    }
  2. Dan letakkan kode di bawah ini di mana Anda tahu nilai-nilai pemintal terbaru hadir, atau di tempat lain sesuai kebutuhan. Sepotong kode ini pada dasarnya menulis nilai pemintal di SharedPreferences.

        Spinner spinner1 = (Spinner) findViewById(R.id.spinner1);
        String spinlong1 = spinner1.getSelectedItem().toString();
        SharedPreferences prfs = getSharedPreferences("WHATEVER",
                Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = prfs.edit();
        editor.putString("SPINNER1_VALUE", spinlong1);
        editor.commit();
pengguna3339073
sumber
0

Saya memiliki masalah yang sama ketika mencoba untuk memilih item yang benar dalam pemintal yang diisi menggunakan cursorLoader. Saya mengambil id dari item yang ingin saya pilih pertama dari tabel 1 dan kemudian menggunakan CursorLoader untuk mengisi spinner. Di onLoadFinished saya mengayuh kursor melewati adaptor pemintal hingga saya menemukan item yang cocok dengan id yang sudah saya miliki. Kemudian tetapkan nomor baris kursor ke posisi pemintal yang dipilih. Akan lebih baik jika memiliki fungsi yang sama untuk memberikan id dari nilai yang ingin Anda pilih di spinner ketika mengisi detail pada formulir yang berisi hasil spinner yang disimpan.

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {  
  adapter.swapCursor(cursor);

  cursor.moveToFirst();

 int row_count = 0;

 int spinner_row = 0;

  while (spinner_row < 0 || row_count < cursor.getCount()){ // loop until end of cursor or the 
                                                             // ID is found 

    int cursorItemID = bCursor.getInt(cursor.getColumnIndexOrThrow(someTable.COLUMN_ID));

    if (knownID==cursorItemID){
    spinner_row  = row_count;  //set the spinner row value to the same value as the cursor row 

    }
cursor.moveToNext();

row_count++;

  }

}

spinner.setSelection(spinner_row ); //set the selected item in the spinner

}
Jaz
sumber
0

Karena beberapa jawaban sebelumnya sangat benar, saya hanya ingin memastikan tidak ada dari Anda yang jatuh dalam masalah ini.

Jika Anda menetapkan nilai ke ArrayListmenggunakan String.format, Anda HARUS mendapatkan posisi nilai menggunakan struktur string yang sama String.format.

Sebuah contoh:

ArrayList<String> myList = new ArrayList<>();
myList.add(String.format(Locale.getDefault() ,"%d", 30));
myList.add(String.format(Locale.getDefault(), "%d", 50));
myList.add(String.format(Locale.getDefault(), "%d", 70));
myList.add(String.format(Locale.getDefault(), "%d", 100));

Anda harus mendapatkan posisi nilai yang dibutuhkan seperti ini:

myList.setSelection(myAdapter.getPosition(String.format(Locale.getDefault(), "%d", 70)));

Jika tidak, Anda akan mendapatkan -1, item tidak ditemukan!

Saya menggunakan Locale.getDefault()karena bahasa Arab .

Saya harap itu akan membantu Anda.

Mohammad AlBanna
sumber
0

Ini adalah solusi mudah-mudahan saya lengkap. Saya telah mengikuti enum:

public enum HTTPMethod {GET, HEAD}

digunakan di kelas berikut

public class WebAddressRecord {
...
public HTTPMethod AccessMethod = HTTPMethod.HEAD;
...

Kode untuk mengatur pemintal oleh HTTPMethod enum-member:

    Spinner mySpinner = (Spinner) findViewById(R.id.spinnerHttpmethod);
    ArrayAdapter<HTTPMethod> adapter = new ArrayAdapter<HTTPMethod>(this, android.R.layout.simple_spinner_item, HTTPMethod.values());
    mySpinner.setAdapter(adapter);
    int selectionPosition= adapter.getPosition(webAddressRecord.AccessMethod);
    mySpinner.setSelection(selectionPosition);

Di mana R.id.spinnerHttpmethoddidefinisikan dalam file tata letak, dan android.R.layout.simple_spinner_itemdisampaikan oleh android-studio.

termigrator
sumber
0
YourAdapter yourAdapter =
            new YourAdapter (getActivity(),
                    R.layout.list_view_item,arrData);

    yourAdapter .setDropDownViewResource(R.layout.list_view_item);
    mySpinner.setAdapter(yourAdapter );


    String strCompare = "Indonesia";

    for (int i = 0; i < arrData.length ; i++){
        if(arrData[i].getCode().equalsIgnoreCase(strCompare)){
                int spinnerPosition = yourAdapter.getPosition(arrData[i]);
                mySpinner.setSelection(spinnerPosition);
        }
    }
pengguna2063903
sumber
Selamat datang di StackOverflow. Jawaban dengan hanya kode di dalamnya cenderung ditandai untuk dihapus karena "berkualitas rendah". Silakan baca bagian bantuan tentang menjawab pertanyaan, kemudian pertimbangkan untuk menambahkan beberapa komentar untuk Jawaban Anda.
Graham
@ user2063903, Silakan tambahkan penjelasan dalam jawaban Anda.
LuFFy
0

sangat sederhana gunakan saja getSelectedItem();

misalnya:

ArrayAdapter<CharSequence> type=ArrayAdapter.createFromResource(this,R.array.admin_typee,android.R.layout.simple_spinner_dropdown_item);
        type.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mainType.setAdapter(type);

String group=mainType.getSelectedItem().toString();

metode di atas mengembalikan nilai string

di atas R.array.admin_typeadalah file sumber daya string dalam nilai

cukup buat file .xml dalam nilai >> string

ahli pc
sumber
0

Misalkan Anda perlu mengisi spinner dari string-array dari resource, dan Anda ingin tetap memilih nilainya dari server. Jadi, ini adalah salah satu cara untuk menetapkan nilai yang dipilih dari server di spinner.

pincodeSpinner.setSelection(resources.getStringArray(R.array.pincodes).indexOf(javaObject.pincode))

Semoga ini bisa membantu! PS kodenya ada di Kotlin!

hetsgandhi
sumber
0

Karena saya memerlukan sesuatu, yang juga berfungsi dengan Pelokalan , saya menemukan dua metode ini:

    private int getArrayPositionForValue(final int arrayResId, final String value) {
        final Resources english = Utils.getLocalizedResources(this, new Locale("en"));
        final List<String> arrayValues = Arrays.asList(english.getStringArray(arrayResId));

        for (int position = 0; position < arrayValues.size(); position++) {
            if (arrayValues.get(position).equalsIgnoreCase(value)) {
                return position;
            }
        }
        Log.w(TAG, "getArrayPosition() --> return 0 (fallback); No index found for value = " + value);
        return 0;
    }

Seperti yang Anda lihat, saya juga menemukan kompleksitas tambahan sensitivitas huruf antara arrays.xml dan valuesaya membandingkannya. Jika Anda tidak memiliki ini, metode di atas dapat disederhanakan menjadi seperti:

return arrayValues.indexOf(value);

Metode pembantu statis

public static Resources getLocalizedResources(Context context, Locale desiredLocale) {
        Configuration conf = context.getResources().getConfiguration();
        conf = new Configuration(conf);
        conf.setLocale(desiredLocale);
        Context localizedContext = context.createConfigurationContext(conf);
        return localizedContext.getResources();
    }
AZOM
sumber
-3

Anda harus melewati adaptor khusus Anda dengan posisi seperti REPEAT [posisi]. dan itu berfungsi dengan baik.

Urvi Jasani
sumber