How does getItem() in an arrayAdapter work? - android

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

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

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

How to set the correct row id to use in onItemClick?

I have onItemClick listener, and I'd like to use the id value. But it has the same value as position.
public void onItemClick(AdapterView<?> a, View view, int position, long id) {
DBh.something(id);
}
I'm using a custom ArrayAdapter similar to the one described here:
onItemClickListener with custom adapter and listview
I also tried to use row.setId(), but its int not long.
I am not asking why you're trying to do this (you probably have your reasons), so will just explain how to do it. As you are already implementing a custom adapter, all you need to do is override the getItemId method:
#Override
public long getItemId(int position) {
//return ID based on the position
return ...;
}
Then this value will be passed into other methods that receive item IDs. Note that if you know how to get the ID from the position, then you can just do it straight in the onItemClickListener, as the position is passed into it.
What exactly is it you want to achieve? In your adapter, you can override "getItemId(int position)", and make it return any Id that you want to give the item. But why use the id value, why not simply use the position?

accessing an item in listview

I have a list of players whos name are displayed listview. and each row of listview contains button, textview and imageview. How can I get the value of textview?
If you are using Custom Adapter class to populate the listview,then in your adapter,you can use HashMap for saving key-value pair,saving position of listitem with the data into that textview.and then you can easily retrieve it on OnItemClickListener of listview.
Depending on the specifics of your implementation, I would go with one of the following approaches.
Option A.
Use setOnItemClickListener to register a click listener with the list (or if you're using a ListActivity or ListFragment simply use [onListItemClick](http://developer.android.com/reference/android/app/ListActivity.html#onListItemClick%28android.widget.ListView, android.view.View, int, long%29)). onItemClick gets passed in the View that was clicked and can be used to retrieve nested views, e.g. the TextView you're looking for.
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView tv = (TextView) view.findViewById(R.id.textview);
String tvText = tv.getText();
}
}
Option B
Assuming you fill your list from some sort of data collection, you may be able to do something similar to above, but use the passed position parameter as an index to directly get the text from the objects in your collection; i.e.:
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
SomeObject so = myCollection.get(position);
String tvText = so.getTextViewText();
}
}
There are lots of more options though. I kind of like creating my own extension of ArrayAdapter to hold the models for the views of the items in the list. That way you could also call getItemAtPosition(int position) or getItem(int position) and cast the returned object to your data type.
Is it a static list or a dynamically generated one? If its a static one you can assign a different id to each textview in the xml itself, and then use FindViewById to access it. If it's not this is what you've got to do: you will obviously have one row and display it many times. So multiple textviews will have same ID. Use a for loop, inside which use FindViewById(Remember FindViewByID will only access the first element with mentioned Id, set its Id to something else, in the next iteration the next textview is selected, set its Id to something) then use these new ids to access them, thus you can access each textview

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