1

I have spinner control and data items bind from sqlite using ormlite, this way:

 public void addItemsOnSpinner()
    {
        DatabaseManager.init(this);

        spinner = (Spinner) findViewById(R.id.spinner2);
        List list = new ArrayList();

        List<Countries> cList = DatabaseManager.getInstance().getAllCountry();


        for (Countries c : cList)
        {
            list.add(c.getcName());

        }
        ArrayAdapter dataAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, list);
        dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(dataAdapter);
    }

So basically, countries names are set as items for my spinner control. It works, however I'm not satisfied with this, because I can only determine current selection by label selected in spinner. Obviously, it's not good because country name is not guaranted to be unique (it's just simple app for education puroposes).

The best solution is to store in my spinner both country name (as spinner label visible for user) and corresponding record id. Id is autogenerated value and of course it's unique, so it can be used to determine selection and read all other propertis from database, using id value, or edit seleted record and save new info to database.

I know how to read/edit record by id. But I have no idea how to store corresponding records ids in my spinner to get know which item was actually selected and how to query database.

Any ideas?

My spinner control is declared as:

<Spinner
        android:id="@+id/spinner2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:prompt="@string/select2" />

I added storing ids as tags, so:

List list = new ArrayList();
        List ids = new ArrayList();

        List<Countries> cList = DatabaseManager.getInstance().getAllCountry();


        for (Countries c : cList)
        {
            list.add(c.getcName());
            ids.add(c.getcID());

        }
        ArrayAdapter dataAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, list);
        dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(dataAdapter);
        spinner.setTag(ids);

Is this ok? Also - how to get current selection tag? For get current item I used: String.valueOf(spinner.getSelectedItem()) but how to read current tag to get my id?

user1209216
  • 7,404
  • 12
  • 60
  • 123

2 Answers2

1

You can store record id in the tag of your Spinner. Do something like this:

int[] recordIds = new int[5];
//init recordIds array
spinner.setTag(recordIds);

You can get id against a country like this:

int[] recordIds = (int[]) spinner.getTag();
int recordIdOfselectedItem = recordIds[spinner.getSelectedItemPosition()];

As you see, index n of country maps to index n of recordId.

Sufian
  • 6,405
  • 16
  • 66
  • 120
  • I read your comment. And I am having the same question. Even if you are using `setTag()` it will not directly map to `id` of that record. Right? – Paritosh Apr 28 '15 at 07:38
  • Um, why not? If the list of countries provided and the list of record ids is basically representing same entry against 0, 1, 2, ... n then it will be fine. – Sufian Apr 28 '15 at 07:40
  • It will break if some record in the middle is `delete`d from the table. Now the code will point to wrong `id`s after deleted id position – Paritosh Apr 28 '15 at 07:43
  • @Paritosh OP hasn't mentioned such a feature. – Sufian Apr 28 '15 at 07:45
  • Won't it be enough to delete item from database and then bind all values to dropdown list again? All old item data will be replaced with current ones, including ids – user1209216 Apr 28 '15 at 07:47
  • @user1209216 yes rebinding the array (to show) and the tag (for record ids) will be enough. – Sufian Apr 28 '15 at 07:48
  • It should work, however I don't like rebinding. Is there any more elegant solution? When I delete/modify data from database, all changes should be populated to my spinner, without any care. Is this possible? To bind only one time. It was possible in WPF for example. – user1209216 Apr 28 '15 at 07:57
  • @user1209216 as I said before, Paritosh's solution is better. You can also check the answer by Narendra. – Sufian Apr 28 '15 at 07:59
  • As far as I understand, I can bind my Countries entity directly to spinner and displayed values will be got from ToString method for each item. But will my changes in entity (delete, update) populated to spinner without need to rebind? – user1209216 Apr 28 '15 at 08:06
  • @user1209216 no. You will always have to set new adapter, unless you're using a custom adapter as suggested by others where you could just do like `adapter.remove(index); adapter.notifyDataSetChanged();`. – Sufian Apr 28 '15 at 08:14
1

You can simply create "Country" custom model with name and id as attributes. Bind this custom countries list to your spinner. Please check this link binding custom objects to spinner

Community
  • 1
  • 1
Narendra
  • 609
  • 1
  • 12
  • 28