What's the Purpose of Item-Id's in Android Listview Adapter

What's the purpose of item-id's in Android ListView Adapter?

There are probably many reasons to have stable item IDs. A default implementation cannot be given since it depends on the type of Object being stored in the Adapter.

Android has a check to make sure that item IDs are used only when they are stabled, i.e. the subclass has properly overridden getItemId; BaseAdapter.hasStableIds must be overriden to return true.

Few reasons I have come across:

  • AdapterView.OnItemClickListener's method onItemClick(AdapterView<?> parent, View view, int position, long id) also sends long id

  • the getCheckedItemIds method The result is only valid if the choice mode has not been set to CHOICE_MODE_NONE and the adapter has stable IDs.

Reply to "Because have to implement that": you don't have to If you don't use the features, there's no need. But if you do, don't forget to override boolean hasStableIds() as well.

Android - what is the meaning of StableIDs?

Stable IDs allow the ListView to optimize for the case when items remain the same between notifyDataSetChanged calls. The IDs it refers to are the ones returned from getItemId.

Without it, the ListView has to recreate all Views since it can't know if the item IDs are the same between data changes (e.g. if the ID is just the index in the data, it has to recreate everything). With it, it can refrain from recreating Views that kept their item IDs.

android-Get id of item in listView

Try to get id from Contact HashMap using list item position of Contact List instead of getting id from TextView text as below :

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(getApplicationContext(), contactList.get(position).get("ID"), Toast.LENGTH_SHORT).show();
}
});

Android - ListView Items with specific IDs

Just follow these steps

  1. Make a simple class having two variables like name and id class name: customer

  2. now make a adapter class extending base adaptor override the getView method and set the text(name) of the customer

  3. Handle clicks in the in listview onitemclick method

So heres a sample code

Pass the adapter an
ArrayList<Customer>

So now your listview will have customer objects

On click you will get the customer object,use the parent.itematposition(position)
Cast the result of this method into customer alike this

Customer c=(Customer)parent.itematposition(position);

System.out.print(c.getId+c.getName());

public class Customer{
private Sting name;
private String id;

Provide setters and getters for both them so that they can be used above

}

Difference between RowId and Position in onItemLongClick's parameter

position is the clicked element's position in your Adapter (so you can do adapter.getItem(position) )

row id is the id that corresponds to that element, what your Adapter returns in the getItemId() method.

Attaching ID data to listview items

Theoretically you could do either approaches and it will probably work without problems. In the long run however, I would say you'll be better of with a simple entity object and a custom adapter. More specifically, from the looks of it, I would opt for an ArrayAdapter, and you already seem to be using some sort of simple entity object for the array ann.

There are tons of examples that can show you how to extend ArrayAdapter. The most important part however is the getView() method, which in it's most basic form could look somewhat like this:

public View getView(int position, View convertView, ViewGroup parent) {
View row;
if (null == convertView) {
row = mInflater.inflate(R.layout.list_item, null);
} else {
row = convertView;
}

MyObject item = (MyObject) getItem(position);

TextView tv = (TextView) row.findViewById(android.R.id.xxx);
tv.setText(item.getTitle);

// same for other fields/views; e.g. author, date etc

return row;
}

In stead of creating a SimpleAdapter, now create an instance of your CustomAdapter, pass it your array (or list) of entity objects, and set the whole as adapter to your list:

MyObject[] objects = ...
setListAdapter(new ArrayAdapter<string>(this, R.layout.list_item, objects));

Since you're now dealing with the objects directly, in stead of first creating a bunch of strings representation out of the different fields, you can also easily access the 'id' of every item. Even better, you can add a whole lot of different fields without worrying how it will look like in the list, since the visual representation is determined by what you set (and don't set) in the getView() method of your adapter.

Assigning ID to a Row in an Android ListView

Here's how I solved the problem. I got the employee_ids and employee_names from the local SQLite Database, then I created an ArrayList of employeeNamesArray and an ArrayList of employeeIdArray at the same time. Thus, the employeeIdArray[0] would match with employeeNameArray[0], employeeIdArray[1] would match with employeeNameArray[1], etc.

Once the ArrayLists were created, I fed employeeNameArray into the ListView.

Later, in onListItemClick, I retreive the position of the selected ListView row. This 'position' will corrospond to the position in the ArrayLists - thus, if I select the first row in the ListView, the position will be zero, and employeeNameArray[0] matches with employeeIdArray[0]. I grab the coroloating entry from employeeIdArray and push that to the next Activity by using putExtra.

public class MyFirstDatabase extends ListActivity {
ArrayList<String> employeeIdArray = new ArrayList<String>(); // List of EmployeeIDs

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Open the database
SQLiteDatabase db;
db = openOrCreateDatabase("mydb.db",SQLiteDatabase.CREATE_IF_NECESSARY, null);
db.setVersion(1);
db.setLocale(Locale.getDefault());
db.setLockingEnabled(true);

// Query the database
Cursor cur = db.query("employee", null, null, null, null, null, "employee_lastname");

cur.moveToFirst(); // move to the begin of the db results

ArrayList<String> employeeNameArray = new ArrayList<String>(); // Initialize mArrayList

while (cur.isAfterLast() == false) {
employeeNameArray.add(cur.getString(1)); // add the employee name to the nameArray
employeeIdArray.add(cur.getString(0)); // add the employee id to the idArray
cur.moveToNext(); // move to the next result set in the cursor
}

cur.close(); // close the cursor

// put the nameArray into the ListView
setListAdapter(new ArrayAdapter<String>(this,R.layout.list_item,employeeNameArray));
ListView lv = getListView();
lv.setTextFilterEnabled(true);
}

protected void onListItemClick(ListView l, View v, final int position, long id) {
super.onListItemClick(l, v, position, id);
Intent myIntent = new Intent(this, SubView.class); // when a row is tapped, load SubView.class

Integer selectionID = Integer.parseInt(employeeIdArray.get(position)); // get the value from employeIdArray which corrosponds to the 'position' of the selected row
myIntent.putExtra("RowID", selectionID); // add selectionID to the Intent

startActivityForResult(myIntent, 0); // display SubView.class

}
}

What does AdapterView? mean in the OnitemClick() Method? What is the use of other parameters in it?

The <?> indicates a Generic. Read more about them here.

Here is what the documentation says about the parameters:

onItemClick(AdapterView<?> parent, View view, int position, long id)

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.

The AdapterView could be a ListView, GridView, Spinner, etc. The question mark inside the angle brackets indicates that it could be any of them. This is called generics in Java. You can use parent in code to do something to the whole view. For example, if you were using a ListView you could hide the whole ListView by the following line of code:

parent.setVisibility(View.GONE);

The View refers to a specific item within the AdapterView. In a ListView it is the row. Thus, you can get a reference to a TextView within a row by saying something like this:

TextView myTextView = (TextView) view.findViewById(R.id.textView1);
String text = myTextView.getText().toString();

The position is the position of the view in the parent. For a ListView, it is the row number. The top row is position 0, the second row is position 1, the third row is position 2, etc. Note that if your ListView has a header view (like if you did ListView.addHeaderView(View)) then the header view would be position 0 and the actual rows would start their numbering at 1.

Sometimes id is the same as position and sometimes it is different. If you are using an ArrayAdapter or SimpleAdapter then they are the same (except in the case that there is a header view and then they are off by one). For a CursorAdapter (and consequently a SimpleCursorAdapter) the id returns the row id of the table, that is, _id.

Here are a few other good answers on this topic:

  • https://stackoverflow.com/a/9863279/3681880
  • https://stackoverflow.com/a/12966006/3681880
  • https://stackoverflow.com/a/24531354/3681880


Related Topics



Leave a reply



Submit