Saving additional context with a view - android

I have GridView which shows a list of thumbnails. After clicking on one of them I'd like to navigate to another activity with detailed view of a corresponding "thing".
How should I store some additional data/identifiers such that on click I can pass it to the detailed activity? By default I only get position and id. I'd like to somehow store my custom identifier which I use to query external services for details.
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
Intent intent = new Intent(this, MovieDetails.class);
intent.putExtra(MY_ID, <some_extra_ID>);
startActivity(intent);
}
});
EDIT:
For example, I have a dynamic list of dishes with only photos of that dish (using GridView). When user clicks on one of them I want to show a detailed view with a recipe and comments.
For that I need to pass name of that dish to load information in the detailed view.

Actually it is as good as a click listener can get as it passes the view, position and id. However you can improve the data you get by defining a unique item id inside your adapter.
If you are using an ArrayAdapter or SimpleAdapter the id is usually the same as position but for a CursorAdapter or SimpleCursorAdapter the id returns the row id of the table.
Now you can extend you adapter and return the desired id inside the getItemId method:
public class MyAdapter extends ArrayAdapter<MyItem>{
...
#Override
public long getItemId(int position) {
return myItems.get(position).myUniqueId;
}
}

Related

Get specific id from a listview

I have a ListView which is implemented using a customs adapter. For making the adapter i am using a holder class. The class has various TextViews and ImageViews as well as an Int variable id to store the id being fetched from the database. Now when i click the particular list i want to get the id so that using it I can further display the information on a new activity. The id is not meant to be displayed in the ListView. How can i get the id from onItemClickListener()
You can set a tag to a View (.setTag()) and then retrieve it, it happens on getView() method inside your custom Adapter
Here is a sample code:
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String transactionId = ((TextView) view
.findViewById(R.id.tvTID)).getText().toString();
handler.getTransactionDetails(callback, transactionId);
}
});
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
YourObject selected = adapter.getItem(position);
Then you can send the selected list item (Object) to your new activity
Intent mIntent = new Intent(ThisActivity.this, NewActivity.class);
mIntent.putExtra("list_selected", selected);
startActivity(mIntent);
as well as an Int variable id to store the id being fetched from the
database.
You didn't provide more infomation about that id (i don't know exactly what it presents) but to make it simple you can set this id for each widget in ListAdapter via setTag() method and then simply retrieve it from your onItemClick() method.

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

Filtering list view and getting correct onclick item

I have a list view and I've implemente filtering.
Lets say I have items A, B and C. If I type B in the filter box, only item B will be displayed and it is the position 0 of the list (before it was in position 1). So when I call the onClick item, I get the the id/position 0, which leads to displaying details about A instead of B.
This is the onclick code:
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Poi poi = pois.get((int)id);
goPOIDETAIL(poi);
}
});
id and position have the same value.
is there a way to get the original position, or get some other value indicating the real item that I clicked?
Thanks
flashsearchList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Integer temp=flashSearchNameMap.get(adapter.getItem(position));
navigateSearch(temp);
}
});
(adapter.getItem(position) will return you the exact list name and in flashSearchNameMap i have stored names and position at beginning from oncreate before applying filtering.So you can get exact position by this
I think the problem is in the way you manage your filter. You should get the object with selected id not from the original List (or array) but from the filtered one.
I used something like it in this post from my blog. Hope this help you
ID and Index are not the same. Of course, you can return item index in getItemId() method of your adapter, but don't expect your items to be identified correctly by this method if you do.
Try providing unique ID for each of your items. The idea is somewhat similar to ID of each record in the database, which never changes (and lets you reliably identify each record), and it is easily implemented when you get your data from database.
But if your items don't have unique IDs, and you don't want to bother providing them, there's another approach (see this example code for Adapter below):
public MyAdapter extends BaseAdapter {
private List<Item> items;
private List<Item> displayedItems;
public MyAdapter(List<Item> items) {
this.items=items;
this.displayedItems=items;
}
public filter(String query) {
if(query.isEmpty()) {
displayedItems=items;
} else {
displayedItems=new ArrayList<Item>();
for (Item item : items) {
displayedItems.add(...) //add items matching your query
}
}
notifyDataSetChanged();
}
//...
//NOTE: we use displayedItems in getSize(), getView() and other callbacks
}
You can try:
#Override
public boolean hasStableIds() {
return false;
}
in your adapter
if you are using datbase you have the _id key that you can load in a filtered list as invisible field. Once you click on the item you can query data with _id key.
If you aren't using a database you could add a hidden id element in your row element as well.

Implementing OnItemClickListener() for a dynamic GirdView/ListView

That GridView adapter creates ImageView from a layout.
All images are downloaded from URLs respect to the database item IDs where the ID is got from a JSONArray.
Let say, the view is now showing items with
ID: 1,3,4,7.
As the GridView items are dynamic, the position (starting from 0) cannot really identify my item on the GridView.
Is there any other ways to identify that image from the database item IDs?
public OnItemClickListener ClickListner = new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Toast.makeText(getApplicationContext(),
// ""+position, Toast.LENGTH_SHORT).show();
//Identification code for the item to be added here
Intent view =
new Intent(main.this, View.class);
view.putExtra("ID", id);
//expected to have an ID equal to database item ID
startActivity(view);
}
};
First option (the nice way)
You keep a reference to your adapter (or you get it by calling parent.getAdapter() and then cast it)
In your adapter make sure that you've overridden getItem(position) to return the object you used to fill up your adapter (probably something like return arrayList.getItem(position)if you used BaseAdapter)
On the adapter you call getItem(position) and this will give you the very same object, so you should have all the info you need now
Second option (easy way out)
You can put info in the gridviewitem's view using setTag()
then in onItemClick you call getTag() and there you have your unique id
You can use a POJO class to set the URL and ID of Image in that class and create and ArrayList for the same and passing that to the Adapter class. By, doing this you will bind your ImageView and the ImageID from your database. And, then inside onItemClick() you can simply use
POJO pojo = listview.getAdapter().getitem(position);
int id = pojo.getId();

passing row data from adapter to new Activity from ListView

I have a ListView which is created with SimpleCursorAdapter.
The list represents merchants. When someone clicks on a merchant i want to view full details of this particular merchant.
on this list (lv1) im setting a listener
lv1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> av, View v, int pos, long id) {
//Cursor merchant = (Cursor) adapter.getItem(pos);
Intent merchant = new Intent(v.getContext(), MerchantView.class);
merchant.putExtra("merchantPosition", pos);
startActivity(merchant);
}
});
How should I pass the data to merchant view in most optimal way?
I have static reference to adapter so I guess I could use somehow getItem call (just as in commented out line) and then pass it as putExtra to Merchant. If that is the way to do it how should I use getItem (I tried couple of times but failed to extract data that i want).
P.S Adapter is making sql query earlier to database with columns - ID,NAME,DESCRIPTION,STATUS
Thanks!
What I do in my Apps, is override the SimpleCursorAdapter.setViewBinder() to set the Tag of Views inside the ListView with the ID from the DB and pass this ID to the intent in the setOnItemClickListener(). Check this question which is a similar case to what you want to do

Categories

Resources