I am creating a list .. the elements of the list are drawn from sqlite database .. I populate the list using ArrayList and ArrayAdapter ...upon clicking the items on the list I want to be able to fire an intent containing info about the item clicked ... info like the index number of the item ..
using the method: onItemClick(AdapterView av, View v, int index, long arg)
I do get index of the item clicked . however it is of the list currently displayed . the problem comes when I do setFilterTextEnabled(true) , and on the app type in some text to to search some item ..and then click it ..rather than giving me the index of the item on the original list it gives me the index on filtered list..
following is the snippet of code:
myListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> av, View v, int index, long arg) {
Intent lyricsViewIntent = new Intent(iginga.this, LyricsPage.class);
lyricsViewIntent.putExtra("title", songList.get((int)arg).getTitle());
lyricsViewIntent.putExtra("id", songList.get((int)arg).getSongId());
startActivity(lyricsViewIntent);
}
});
myListView.setTextFilterEnabled(true);
Is there any way I can get the original index /position of the item instead of the one showing in filtered text ...when filtered.
I had a bit of a wrestle with this problem recently, and the solution turns out to be fairly simple. You can retrieve the "visible list" by using getListAdapter()
on the ListActivity
, which reflects the current filtered view of the list.
For example, in your ListActivity
subclass's onCreate()
:
final ListView listView = getListView();
final ListAdapter listAdapter = getListAdapter();
listView .setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
MyClass item = (MyClass) listAdapter .getItem(position);
// now do something with that item
}
});
So, ignore the "original" list that you put into the list adapter, and instead ask for the list from the adapter each time the event comes in.
Abhinav I completely understand your problem as I have been struggling with the same issue for the past two days. I didn't realize the values of "int position" and "int id" change as you use the soft keyboard to filter data until I started using breakpoints on the debugger. Hope this code can give you a better idea of how to fix your issues. I ended up writing a for loop so that I could match the toString() of the filtered list with the toString() of the unfiltered list. This way I could retrieve/correct the "int position" value.
public class FacultyActivity extends ListActivity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Retrieves the array stored in strings.xml
final String[] facultyList1 = getResources().getStringArray(R.array.professor_name);
final String[] facultyList2 = getResources().getStringArray(R.array.professor_email);
// Develop an array based on the list_view.xml template
setListAdapter(new ArrayAdapter<String>(this, R.layout.faculty, facultyList1));
final ListView lv = getListView();
// Allow the user to filter the array based on text input
lv.setTextFilterEnabled(true);
// Handle the user event where the user clicks on a professor's name
lv.setOnItemClickListener(new OnItemClickListener()
{
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
/* Filtering text changes the size of the array[index]. By clicking on a filtered
* entry the int position and long id does not correlate to the original array list.
* This block of code will search the original array based on the toString() function
* and for loop the orignial array to find the matching string, retrieving the
* correct index/position.
*/
String name = lv.getItemAtPosition(position).toString();
for (int index = 0; index < facultyList1.length; index++)
{
if (name.equals(facultyList1[index]))
{
position = index;
break;
}
}
Bundle bundle = new Bundle();
bundle.putString("email", facultyList2[position]);
startActivity(new Intent(FacultyActivity.this, EmailActivity.class).putExtras(bundle));
}
});
}
}
One of the ways of doing this could be Tagging the view with its index when drawing them View#setTag()
and reading them when ever you want with View#getTag()
I think that this is a bug that should be fixed: if you click (with the mouse) on entry number 150 for instance, you get back the name of entry 150 and an id of 150. But if you type in characters that give you entry 150 back and it's the first of three with the same characters you've typed in, you get back 0 and the name of entry 0 (which of course in your original list is not what you want). This should return the id and name for entry 150 if filtered and to have to do what abhinav did above (albeit, useful and worked for me), is kludgy in my not so humble opinion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With