Search code examples
javaandroidargument-passing

How to make Android list item pass id on to next view?


In my (first) Android App I have a list of items. Each item is displayed using item.xml in which I have a RelativeLayout. In this layout I defined android:onClick="showItemDetails" of which the method looks like this:

public void showItemDetails(View view) {
    Intent intent = new Intent(this, itemDetails.class);
    intent.putExtra("itemId", "5");
    this.startActivity(intent);
}

As you can see I pass on a hardcoded id, so whatever item you currently click on, it obviously only shows item nr 5. I now need to dynamically give this method the id. The itemlist is created in the ItemListAdapter class of which a part is this:

holder.description.setText(rowItem.eventDescription);
holder.amount.setText(rowItem.getDisplayAmount());

I also have the id under rowItem.id, but I'm kinda lost on what I should do with it.

Can anybody help me out a bit here? What do I need to do to have the list items correctly pass the id through to the itemDetails class? All tips are welcome!


Solution

  • First few assumptions:

    • you're not using Fragments just plain Activity called OuterActivityClass
    • rowItem var has typ RowItemClass
    • your ItemListAdapter is extending ArrayAdapter<RowItemClass>
    • you do it "right" (ItemListAdapter do not have own List<RowItemClass> field, rowItem in getView(...) is assigned like rowItem = getItem(possition); not like rowItem = yourListFieldInAdapter.get(position);(I do not know why Ppls using such field sinceArrayAdapter<?> already has it internally) ... if you do it "bad" replace all getItem(possition) occurrence in my answer with yourListFieldInAdapter.get(position)
    • id field of RowItemClass is long or int (if not use "or:" version)

    What you have to do:

    1. get rid of android:onClick from item.xml
    2. override hasStableIds() in ItemListAdapter: public boolean hasStableIds () { return true; }
    3. override getItemId(...) in adapter: public long getItemId (int position) { return getItem(position).id; }
    4. in Activity onCreate(...) get ListView: ListView listView = findViewById(R.id.your_listview_id);
    5. then assign the listener to your listView(in onCreate, too)

    code:

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
       void onItemClick(AdapterView<?> parent, View view, int position, long id){
          Intent intent = new Intent(OuterActivityClass.this, itemDetails.class);
          intent.putExtra("itemId", id + ""); //+ "" to make it string, of course you can use long but you have to remeber to use intent.getLongExtra(...) in details Activity
          startActivity(intent);
       }
    });
    

    or:

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
       void onItemClick(AdapterView<?> parent, View view, int position, long id){
          final RowItemClass clickedItem  = (RowItemClass)parent.getItemAtPosition(position);
          Intent intent = new Intent(OuterActivityClass.this, itemDetails.class);
          intent.putExtra("itemId", clickedItem.id + "");
          startActivity(intent);
       }
    });
    

    with second method you can omit points 2. and 3. (if you are using "bad" way remeber to override getItem (return yourListFieldInAdapter.get(pos)) and getCount( return yourListFieldInAdapter.size())in your adapter implementation)

    Offtopic hint: do not use lower case as first letter in class name itemDetails => ItemDetails ... for your sanity :) (OMG, OMG, itemDetails is variable or class name )