How to access position variable in onItemSelected() - android

In the following example, how would I access the "position" variable from outside the parent class?
void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Country country = (Country) parent.getAdapter().getItem(position);
spinner2.setAdapter(new ArrayAdapter(country.getStates());
}

You could pass the position value outside, but you also have to know something about the adapter and the data source of the adapter. If your adapter is using an array for the data source, position is usually the position of the item in the array. So if you have some other access point to the array, the position would be that element. If the data source of the adapter is a Cursor, position won't help you much outside because you can't be sure of which record the Cursor was pointing to at that position. So unfortunately, the answer is "it depends". Using id is better if the data source is a content provider since you can append the id to the base Uri and access the record that way outside of this callback.

Related

How do I get a model instance associated with a listview row using setTag(int, object)?

I have a listview itemClickListener that should get the model instance associated with the row clicked.
I read about tags in http://developer.android.com/reference/android/view/View.html#setTag(int, java.lang.Object)
I know that listview recycles rows, so it would not be a good idea to use v.setTag(currentItem), because that would result in an earlier row being associated with a later item.
So to solve my original problem, it looks like I need to use setTag(int, object) where the body of my click handler needs to know the unique key. The documentation states to use a resource id value, but that is not unique amongst multiple rows. How do I get the model instance for the row I clicked on?
You should just be able to grab the item out of your adapter like this:
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
ListAdapter a = (ListAdapter)parent.getAdapter();
Object itemAtPosition = a.getItem(position);
}

Including Row ID from MySQL Table in Android ListView (for each list item)

When I grab info from a database (I am using MySQL), I'd like to also grab the id of the row and somehow assign it to each row of the 'listView`.
For example, let's say there is a table called fruit. fruit_id of 16 is orange. When the listView displays the list of fruit, and user clicks on a row that shows orange, i'd like to be able to access the fruit_id(16) of that row. But I'm not sure where to "hide" it.
Doing some initial research it seems there are multiple ways one can do this. The simplest might be something with using a tag, is this the best way? if so, how can you assign an id to it?
Create a class named Fruit.
class Fruit {
private int fruit_id;
private String fruit_name;
// Constructors
// Getters and Setters
}
Use an ArrayAdapter<Fruit> as the ListAdapter for your ListView. Then at ListView's onItemClickListener, get the Fruit object and get its id.
If you're using an ArrayAdapter to back your ListView, then #jaibatrik's suggestion is definitely a good one. However, if you're using a CursorAdapter, it's probably easier to exploit the return value of getItemId().
By default, a CursorAdapter will look for a column with the name "_id" in the Cursor you supply it and return that as id value whenever you click an item:
onItemClick(AdapterView<?> parent, View view, int position, long id)
That last value will contain the id of your cursor item. You can also override this behaviour and have it return any other unique value you may have access to in the Cursor.
The same is also true for an ArrayAdapter: by default it will return the position of the item in the array as unique id. However, you could easily make it return fruit_id for every item by overriding that method. Then it'll be passed in the onItemClick(...) directly, which saves you retrieving it (again) in there.
My questions is, if I grab, for example, item_id (not just item),
where do I put item_id in the listView rows (on Android side)?
The beauty of having objects that represent the data you're visualising in the list, is that you already have all the ingredients to make it work. Let's take the Fruit example given by #jaibatrik and add one getter for the sake of this example:
class Fruit {
private int fruit_id;
private String fruit_name;
// Constructors
// Getters and Setters
public int getId() { return fruit_id; }
}
In the comments you're describing you retrieve the fruit data from the database and populate it in a list:
List<Fruit> fruits = ...
That list should be the dataset backing your ArrayAdapter. To be more specific, since it's a typed class, you should have an ArrayAdapter<Fruit> instance that you set as adapter to the ListView.
Now, assuming you have an OnItemClickListener set against the ListView, it will fire whenever the user taps on an item. Using the parameters passed into the callback, you can retrieve the item that is associated with the position that was selected:
#Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Fruit fruit = (Fruit) parent.getItemAtPosition(position);
int fruit_id = fruit.getId();
...
}
With the object retrieved, you can do anything you like with the data it holds. No need to explicitly set the id against the row views, since it should already be part of the dataset that backs the ListView.

How does getItem() in an arrayAdapter work?

I've read lots of tutorials from my manual and on the internet that explain the getView method, but I haven't understood why they use it.
Could anyone explain it to me with some examples or snippets?
getItem() returns the item's data object. It provides a way for you to access data in the adapter. For example, your array adapter holds string elements, getItem() returns a string object.
getView() is used to construct or reuse the child item of your AdapterView.
AdapterView is a view that contains multiple items. For example, a ListView contains some items that have the same (or might not) structure. getView() is used to build the View at some position and fill it with data.
getItem() is used to get the item that provides a data for the specified View item.
For example, getItem() must return a String or CharSequence if you have a ListView of text items. This is made for convenience, for example in your onItemClickListener
#Override
public void onItemClick(AdapterView<?> av, View view, int pos,
long arg3) {
String selectedText = (String) av.getItemAtPosition(pos);
// or av.getAdapter().getItem(pos);
}

Getting data from custom list view on click

I have a custom ListView with two TextViews both containing different values. What I want to be able to do it get the contents from one of these TextViews when an item is clicked.
This is the code I have so far:
listView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String value;
// value = (get value of TextView here)
}
});
I want to be able to assign value to the text of one of the TextView's.
Although #Sam's suggestions will work fine in most scenarios, I actually prefer using the supplied AdapterView in onItemClick(...) for this:
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Person person = (Person) parent.getItemAtPosition(position);
// ...
}
I consider this to be a slightly more fool-proof approach, as the AdapterView will take into account any header views that may potentially be added using ListView.addHeaderView(...).
For example, if your ListView contains one header, tapping on the first item supplied by the adapter will result in the position variable having a value of 1 (rather than 0, which is the default case for no headers), since the header occupies position 0. Hence, it's very easy to mistakenly retrieve the wrong data for a position and introduce an ArrayIndexOutOfBoundsException for the last list item. By retrieving the item from the AdapterView, the position is automatically correctly offset. You can of course manually correct it too, but why not use the tools provided? :)
Just FYI and FWIW.
You have a few options. I reference the code from your previous question.
You can access this data from the row's layout view:
ViewHolder holder = (ViewHolder) view.getTag();
// Now use holder.name.getText().toString() and holder.description as you please
You can access the Adapter with position:
Person person = mAdapter.getItem(position);
// Now use person.name and person.description as you please
(By the way in your Person class, name and description are public so you don't need the get methods.)
Override following method in adaterclass.
public String[] getText() {
return text;
}

onItemClick ... passing the position in my array to somewhere else

Does the "position" parameter in the onItemClick reference the position in the Adapter, which might include, say, the footer and header as well. I'm asking because I want to be able to pass the actual position in the underlying array that I'm using with my adapter. Can I just pass "position" and I'll be good to go?
If I remember correctly the position is the position in your items array. Header and footer items I do not think get included, because your overridden method getPosition() simple returns the position you are seeking within the array of items.
In answer to your question, yes, headers and footers are included in the position parameter.
The documentation for onItemClick states the parameters are as follows:
parent The AdapterView where the click happened.
view The view within the AdapterView that was clicked (this will be a view provided by the adapter)
position The position of the view in the adapter.
id The row id of the item that was clicked.
So if you're looking to fetch an object from your underlying array, you should use the long id parameter instead, which returns the underlying array index:
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
// Get the item that was clicked
Object objectToUse = myAdapter.getItem( (int) id );
}

Categories

Resources