Làm cách nào để đặt mục được chọn của Spinner theo giá trị, không phải theo vị trí?


297

Tôi có chế độ xem cập nhật, nơi tôi cần chọn trước giá trị được lưu trữ trong cơ sở dữ liệu cho Spinner.

Tôi đã nghĩ đến một cái gì đó như thế này, nhưng Adapterkhông có indexOfphương pháp, vì vậy tôi bị mắc kẹt.

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

Câu trả lời:


646

Giả sử Spinnertên của bạn được đặt tên mSpinnervà nó chứa một trong những lựa chọn của nó: "một số giá trị".

Để tìm và so sánh vị trí của "một số giá trị" trong Spinner, hãy sử dụng:

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);
}

5
với một bộ điều hợp tùy chỉnh, bạn sẽ phải viết (ghi đè) mã cho getP vị trí ()
Soham

3
Sẽ thế nào nếu bạn không kiểm tra chuỗi nhưng một phần tử bên trong một đối tượng và không thể chỉ sử dụng toString () khiến giá trị của spinner thay đổi từ đầu ra của toString ().
Ajibola

1
Tôi biết điều này đã rất cũ, nhưng giờ đây nó đã ném một cuộc gọi không được kiểm tra tới getP vị trí (T)
Brad Bass

có lỗi tương tự, nhưng sử dụng cách học cũ này đã giúp: stackoverflow.com/questions/25632549/iêu
Manny265

Hmm ... Bây giờ nếu tôi lấy giá trị từ Parse.com và muốn truy vấn người dùng để lựa chọn spinner mặc định được mặc định là giá trị cơ sở dữ liệu của người dùng thì sao?
drearypanoramic

141

Một cách đơn giản để đặt spinner dựa trên giá trị là

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;
 } 

Cách để mã phức tạp đã có, điều này chỉ đơn giản hơn nhiều.


7
Bạn đã quên thêm break;khi chỉ mục được tìm thấy để tăng tốc quá trình.
spacebiker

tại sao không sử dụng do {} while () để tránh sử dụng break?
Catluc

@Catluc có n số cách để đi đến giải pháp, bạn chọn ... cách nào phù hợp nhất với bạn
Akhil Jain

4
Thay vào đó 0, bạn nên trả về -1nếu không tìm thấy giá trị - như được hiển thị trong câu trả lời của tôi: stackoverflow.com/a/32377917/1617737 :-)
ban-Geoengineering

2
@ ban-Geoengineering Tôi đã viết 0như một kịch bản sao lưu. Nếu bạn đặt -1, mục nào sẽ hiển thị ở spinner, tôi cho rằng phần tử thứ 0 của bộ điều hợp spinner, thêm -1 cũng làm tăng thêm việc kiểm tra xem giá trị có phải là -1 hay không, vì cài đặt -1 sẽ gây ra ngoại lệ.
Akhil Jain

34

Tôi giữ một ArrayList riêng của tất cả các mục trong Spinners của tôi. Bằng cách này, tôi có thể thực hiện indexOf trên ArrayList và sau đó sử dụng giá trị đó để đặt lựa chọn trong Spinner.


Không có cách nào khác, bạn biết không?
Pentium10

1
Làm thế nào để thiết lập lựa chọn thành không có gì? (nếu mặt hàng không có trong danh sách)
Pentium10

5
HashMap.get sẽ cho tốc độ tra cứu tốt hơn ArrayList.indexOf
Dandre Allison

29

Dựa trên câu trả lời của Merrill , tôi đã đưa ra giải pháp một dòng này ... nó không hay lắm, nhưng bạn có thể đổ lỗi cho bất cứ ai duy trì mã Spinnervì đã bỏ qua việc bao gồm một hàm thực hiện điều đó.

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

Bạn sẽ nhận được một cảnh báo về cách bỏ chọn cho một diễn viên ArrayAdapter<String>... thực sự, bạn chỉ có thể sử dụng một ArrayAdapternhư Merrill đã làm, nhưng điều đó chỉ trao đổi một cảnh báo cho người khác.


Để thoát khỏi cảnh báo không được kiểm tra, bạn nên sử dụng <? > trong dàn diễn viên của bạn thay vì <String>. Trong thực tế, bất cứ khi nào bạn sử dụng bất cứ thứ gì với một loại, bạn nên sử dụng <? >.
xbakesx

Không, nếu tôi chọn một <? > nó báo lỗi cho tôi thay vì cảnh báo: "Phương thức getP vị trí (?) trong kiểu ArrayAd CHƯƠNG <?> không áp dụng cho đối số (Chuỗi)."
ArtOfWarfare

Chính xác, sau đó nó sẽ nghĩ rằng đó là một ArrayAd CHƯƠNG không có loại, do đó, nó sẽ không cho rằng đó là một ArrayAd CHƯƠNG <String>. Vì vậy, để tránh cảnh báo, bạn sẽ cần chuyển nó sang ArrayAd CHƯƠNG <? > sau đó chuyển kết quả của adapter.get () thành Chuỗi.
xbakesx

@Dadani - Tôi hiểu rằng bạn chưa bao giờ sử dụng Python trước đây, vì điều này thật ngu ngốc.
ArtOfWarfare

Đồng ý, tôi chưa chơi với Python @ArtOfWarfare, nhưng đây là cách nhanh chóng cho một số tác vụ nhất định.
Daniel Dut

13

Nếu bạn đang sử dụng mảng chuỗi thì đây là cách tốt nhất:

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

10

Bạn cũng có thể sử dụng cái này,

String[] baths = getResources().getStringArray(R.array.array_baths);
mSpnBaths.setSelection(Arrays.asList(baths).indexOf(value_here));

Công việc tuyệt vời!
Sadman Hasan

8

Nếu bạn cần có một phương thức indexOf trên bất kỳ Bộ điều hợp cũ nào (và bạn không biết triển khai cơ bản) thì bạn có thể sử dụng phương thức này:

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;
}

7

Dựa trên câu trả lời của Merrill ở đây là cách thực hiện với CthonAd CHƯƠNG

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;
        }
    }

6

Sử dụng dòng sau để chọn sử dụng giá trị:

mSpinner.setSelection(yourList.indexOf("value"));

3

Tôi đang sử dụng một bộ chuyển đổi tùy chỉnh, vì mã này là đủ:

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

Vì vậy, đoạn mã của bạn sẽ như thế này:

void setSpinner(String value)
    {
         yourSpinner.setSelection(arrayAdapter.getPosition(value));
    }

3

Đây là phương pháp đơn giản của tôi để lấy chỉ mục theo chuỗi.

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;
}

3

Bạn có thể sử dụng cách này, chỉ cần làm cho mã của bạn đơn giản hơn và rõ ràng hơn.

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

Hy vọng nó giúp.


2

đây là giải pháp của tôi

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()));

và getItemIndexById bên dưới

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

Hy vọng điều này giúp đỡ!


2

Dưới đây là cách thực hiện nếu bạn đang sử dụng SimpleCursorAdapter( columnNametên của cột db mà bạn đã sử dụng để điền vào 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;
    }
}

Ngoài ra (sàng lọc câu trả lời của Akhil ) đây là cách tương ứng để làm điều đó nếu bạn điền Spinner của mình từ một mảng:

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
    }
};

1

Nếu bạn đặt một mảng XML thành spinner trong bố cục XML, bạn có thể làm điều này

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);
      }
   }
}

0

Thực sự có một cách để có được điều này bằng cách sử dụng tìm kiếm chỉ mục trên AdapterArray và tất cả điều này có thể được thực hiện với sự phản chiếu. Tôi thậm chí còn tiến thêm một bước khi tôi có 10 Spinners và muốn thiết lập chúng một cách linh hoạt từ cơ sở dữ liệu của mình và cơ sở dữ liệu chỉ giữ giá trị không phải là văn bản vì Spinner thực sự thay đổi từ tuần này sang tuần khác vì vậy giá trị là số id của tôi từ cơ sở dữ liệu.

 // 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);

}

Dưới đây là tìm kiếm được lập chỉ mục mà bạn có thể sử dụng trên hầu hết mọi danh sách miễn là các trường nằm ở cấp cao nhất của đối tượng.

    /**
 * 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
}

Phương thức truyền có thể được tạo cho tất cả các nguyên hàm ở đây là một phương thức cho chuỗi và 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;
}

0

Để làm cho ứng dụng ghi nhớ các giá trị spinner được chọn cuối cùng, bạn có thể sử dụng mã bên dưới:

  1. Mã bên dưới đọc giá trị spinner và đặt vị trí spinner tương ứng.

    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. Và đặt mã bên dưới nơi bạn biết các giá trị spinner mới nhất hiện diện hoặc ở một nơi khác theo yêu cầu. Đoạn mã này về cơ bản ghi giá trị spinner trong 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();

0

Tôi đã gặp vấn đề tương tự khi cố gắng chọn mục chính xác trong một công cụ quay vòng được sử dụng bằng cách sử dụng con trỏ. Tôi đã lấy id của mục tôi muốn chọn đầu tiên từ bảng 1 và sau đó sử dụng CoderLoader để điền vào spinner. Trong onLoadFinished, tôi đã đạp xe qua con trỏ điền vào bộ điều hợp của spinner cho đến khi tôi tìm thấy mục phù hợp với id mà tôi đã có. Sau đó gán số hàng của con trỏ cho vị trí đã chọn của spinner. Sẽ thật tuyệt nếu có một hàm tương tự để chuyển vào id của giá trị bạn muốn chọn trong công cụ quay vòng khi điền chi tiết vào biểu mẫu có chứa kết quả của công cụ lưu trữ đã lưu.

@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

}

0

Vì một số câu trả lời trước đây rất đúng, tôi chỉ muốn chắc chắn rằng không ai trong số các bạn rơi vào vấn đề như vậy.

Nếu bạn đặt các giá trị thành ArrayListsử dụng String.format, bạn PHẢI có được vị trí của giá trị bằng cách sử dụng cùng một cấu trúc chuỗi String.format.

Một ví dụ:

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

Bạn phải có được vị trí của giá trị cần thiết như thế này:

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

Nếu không, bạn sẽ nhận được -1, không tìm thấy mục!

Tôi đã sử dụng Locale.getDefault()ngôn ngữ Ả Rập .

Tôi hy vọng điều đó sẽ hữu ích cho bạn.


0

Đây là giải pháp hy vọng đầy đủ của tôi. Tôi có enum sau:

public enum HTTPMethod {GET, HEAD}

được sử dụng trong lớp sau

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

Mã để đặt spinner theo HTTPMethod enum-thành viên:

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

Trường hợp R.id.spinnerHttpmethodđược xác định trong tệp bố cục và android.R.layout.simple_spinner_itemđược phân phối bởi android-studio.


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);
        }
    }

Chào mừng bạn đến với StackOverflow. Câu trả lời chỉ có mã trong đó có xu hướng bị gắn cờ để xóa vì chúng "chất lượng thấp". Vui lòng đọc phần trợ giúp về trả lời câu hỏi sau đó xem xét thêm một số bình luận vào Câu trả lời của bạn.
Graham

@ user2063903, Vui lòng thêm giải thích trong câu trả lời của bạn.
LuFFy

0

rất đơn giản chỉ cần sử dụng getSelectedItem();

ví dụ :

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();

phương thức trên trả về một giá trị chuỗi

ở trên R.array.admin_typelà một tệp tài nguyên chuỗi trong các giá trị

chỉ cần tạo tệp .xml trong các giá trị >> chuỗi


0

Giả sử bạn cần điền spinner từ mảng chuỗi từ tài nguyên và bạn muốn giữ giá trị được chọn từ máy chủ. Vì vậy, đây là một cách để đặt giá trị được chọn từ máy chủ trong công cụ quay vòng.

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

Hy vọng nó giúp! PS mã là trong Kotlin!


0

Vì tôi cần một cái gì đó, cũng hoạt động với Bản địa hóa , tôi đã đưa ra hai phương pháp sau:

    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;
    }

Như bạn có thể thấy, tôi cũng vấp phải sự phức tạp thêm về độ nhạy trường hợp giữa mảng Arrayays và valuetôi đang so sánh với. Nếu bạn không có điều này, phương pháp trên có thể được đơn giản hóa thành một cái gì đó như:

return arrayValues.indexOf(value);

Phương pháp trợ giúp tĩnh

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();
    }

-3

bạn phải vượt qua bộ điều hợp tùy chỉnh của mình với vị trí như REPEAT [vị trí]. và nó hoạt động đúng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.