简体   繁体   中英

Best practice to implement key-value pair in android Spinner

I want to implement an android spinner with key value .

en:english jp:japanese

And when user select and item I want to save key to database . And also on next load I want spinner to select a particulate spinner position.

Can any one please tell me what is the best way to implement this.

I have tried following but doesn't met my requirement https://gist.github.com/granoeste/2786663 Set Key and Value in spinner

Write now I am using LinkedHashMapAdapter. But issue is that here I need to store position in DB or local shared preference . I don't think this a better solution

Current Implementation

LinkedHashMap localeList = new LinkedHashMap<>();

        for (Map.Entry<String, String> val : map.entrySet()) {
            int resourceId = getResources().getIdentifier(val.getValue(), "string", getPackageName());
            localeList.put(val.getKey(), getResources().getString(resourceId));

        }
        LinkedHashMapAdapter<String, String> arrayAdapter = new LinkedHashMapAdapter<>(this, R.layout.spinner_layout, localeList);
        arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        mLocale.setAdapter(arrayAdapter);
        String localPosSelected = PreferencesHelper.getSharedPreferenceString(this, Constants.PREF_LOCALE_POS_KEY);
        if(localPosSelected!=null){
            mLocale.setSelection(Integer.parseInt(localPosSelected));
        }

Also is there an option to selected item of Spinner by value

setup Spinner:

        spLang = (Spinner)view.findViewById( R.id.spLang );
        spLang.setOnItemSelectedListener( this );
        ArrayList<String> sp_Lang = new ArrayList<String>();
        sp_Lang.add("english");
        sp_Lang.add("french");
        ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this,
                    android.R.layout.simple_spinner_item, sp_Lang);
        spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spLang.setAdapter(spinnerAdapter);

For Perticular Spinner item Selection:

int Position = spinnerAdapter.getPosition("Japanese");
spLang.setSelection(Position);

First Create Hashmap for store Key and value pair

HashMap<String ,String> hmLang = new HashMap<String,String>();

Now Add value like this into HashMap :

hmLang.put("english" ,"en");

Here in HashMap key = YourValue and Value = yourKey

@Override
public void onItemSelected(AdapterView<?> adapterView, View view, int position, long id) {
    switch(adapterView.getId())
    {
        case R.id.spLang:
        String lang_Name = adapterView.getItemAtPosition(position).toString();
        String lang_Key = hmLang.get(lang_Name);
        break

    }

If you have any issue with this code then please ask

I created using an HashMap adapter for use in these scenarios. Also see example project here

  mapData = new LinkedHashMap<String, String>();

    mapData.put("shamu", "Nexus 6");
    mapData.put("fugu", "Nexus Player");
    mapData.put("volantisg", "Nexus 9 (LTE)");
    mapData.put("volantis", "Nexus 9 (Wi-Fi)");
    mapData.put("hammerhead", "Nexus 5 (GSM/LTE)");
    mapData.put("razor", "Nexus 7 [2013] (Wi-Fi)");
    mapData.put("razorg", "Nexus 7 [2013] (Mobile)");
    mapData.put("mantaray", "Nexus 10");
    mapData.put("occam", "Nexus 4");
    mapData.put("nakasi", "Nexus 7 (Wi-Fi)");
    mapData.put("nakasig", "Nexus 7 (Mobile)");
    mapData.put("tungsten", "Nexus Q");

    adapter = new LinkedHashMapAdapter<String, String>(this, android.R.layout.simple_spinner_item, mapData);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    spinner = (Spinner) findViewById(R.id.spinner);
    spinner.setAdapter(adapter);
    spinner.setOnItemSelectedListener(this);

You can save selected spinner item position in database and next time set the spinner item by saved position

To get position:
int position = spinner1.getSelectedItemPosition();

For setting:
spinner.setSelection(position);

notice that you should call setSelection() method after setting spinner adapter

you can create custom adapter for spinner to achieve this.

With use of custom adapter

  • you will able to use your hashMap for key value pair.
  • you can pass your custom view to change.

Populate Spinner

void populateRecordPerPageSpinner(LinkedTreeMap<String, String> map) {
        String selectedValue = PreferencesHelper.getSharedPreferenceString(context, Constants.PREF_RECORD_PER_PAGE_KEY);
        List<String> recordPerPageList = new ArrayList();

        for (Map.Entry<String, String> val : map.entrySet()) {
            int resourceId = getResources().getIdentifier(val.getValue(), "string", getPackageName());
            recordPerPageMap.put(val.getKey(), getResources().getString(resourceId));
            recordPerPageList.add(getResources().getString(resourceId));
        }
        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this, R.layout.spinner_layout, recordPerPageList);
        arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mRecordPerPage.setAdapter(arrayAdapter);
        mRecordPerPage.setSelection(arrayAdapter.getPosition(selectedValue));

    }

Fetch and save position in preference

selectedRecPerPage = recordPerPageMap.get(mRecordPerPage.getAdapter().getItem(recordPerPagePosition));
PreferencesHelper.setSharedPreferenceString(context, Constants.PREF_RECORD_PER_PAGE_KEY, selectedRecPerPage);

I have updated Dhaval's answer to be more generic. This solution utilizes toString() and ArrayAdapter (you do not need to implement your own adapter with all the logic) and is implemented in Kotlin

Create your custom class and override toString() method.

data class SpinnerEntry(
    // define whatever properties you want
    val label: String,
    val key: MyEnum,
) {
    override fun toString(): String {
        return label // this will display to user
    }
}

Initialize spinner

val entries = listOf(
    // you want to extract string resources to XML
    SpinnerEntry("LabelA", MyEnum.A),
    SpinnerEntry("LabelB", MyEnum.B),
    SpinnerEntry("LabelC", MyEnum.C),
    SpinnerEntry("LabelD", MyEnum.D),
)

spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
    override fun onItemSelected(
        parent: AdapterView<*>?,
        view: View?,
        position: Int,
        id: Long
    ) {
        val selectedItem = parent?.getItemAtPosition(position) as SpinnerEntry
        val key = selectedItem.key
        // do something with selected key
    }

    override fun onNothingSelected(parent: AdapterView<*>?) {
        // do something when unselected
    }
}

val spinnerAdapter: ArrayAdapter<SpinnerEntry> = ArrayAdapter(
    applicationContext!!, // get context depending on your implementation
    android.R.layout.simple_spinner_item,
    entries
)
            
spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
spinner.adapter = spinnerAdapter

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM