OnItemClick gives the index / position of the element on the visible page ... not the actual index of the element in the list ..issue when you enable setTextFilterEnabled

I am creating a list. List items are retrieved from the sqlite database .. I populate the list using ArrayList and ArrayAdapter ... after clicking on the items in the list, I want to be able to run an intent containing information about the item clicked ... the information resembles the index number of the item.

using method: onItemClick (AdapterView av, View v, int index, long arg)

I get the index of the item clicked. however, it appears in the list. The problem occurs when I set setFilterTextEnabled (true), and in the application type - in some text to look for some element .. and then click on it. Instead of specifying the index of the item in the source list, it gives me the index in the filtered list.

The following is a 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 a way to get the source index / position of the element instead of the one that appears in the filtered text ... when filtering.

+4
source share
6 answers

I recently had a battle with this problem and the solution turned out to be quite simple. You can get the “visible list” using getListAdapter() in the ListActivity , which reflects the current filtered view of the list.

For example, in a subclass of ListActivity 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 in the list adapter, and instead request the list from the adapter every time an event arrives.

+9
source

Abhinav I fully understand your problem as I struggled with the same problem in the last two days. I did not know that the values ​​of "int position" and "int id" change when you use a soft keyboard to filter data until I start using breakpoints on the debugger. Hope this code can give you a better idea on how to fix your problems. I ended up writing a for loop so that I can match the toString () of the filtered list with the toString () of the unfiltered list. That way I could get / fix the value of "int position".

 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 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)); } }); } } 
+3
source

One way to do this is to mark the view with its index when you draw View#setTag() and read them whenever you want with View#getTag()

+1
source

I think this is a mistake that needs to be fixed: if you click (with the mouse) on the record number 150, for example, you will return the record name 150 and the identifier 150. But if you enter the characters that give you the record 150 back, and it the first of three with the same characters that you entered, you will return 0 and the entry name is 0 (which, of course, is not what you want in your original list). This should return the id and name for entry 150, if filtered, and doing what abhinav did (although useful and worked for me) is kludgy in my not very humble opinion.

+1
source

In the Adapter class, override the following methods with the following code.

 @Override public long getItemId(int position) { return position; } @Override public int getPosition(StateFlower item) { return allItemsArray.indexOf(item); } @Override public StateFlower getItem(int arg0) { return allItemsArray.get(arg0); } 
0
source

I just found a simple solution to the same problem. First question, in your adapter, are you using ArrayList <String> or String []?
Try creating a class to hold the required information.
And then, use ArrayList <DataHoldingClass> in your adapter.
For instance:

 public class DataHoldingClass { private Integer id; private String name; public DataHoldingClass(Integer id,String name){ this.id=id; this.name=name; } public Integer getDataId(){ return id; } @Override public String toString() { return name; } //implements getters and setters to name and other fields if you want } 

You must override the toString () method so that the adapter knows what information is displayed in the list. Then, somewhere in the code:

 ArrayList< DataHoldingClass> info = new ArrayList<DataHoldingClass>(); info.add( new DataHoldingClass(id,name) ) //here you populate the ArrayList with the desired informations to be showed at List adapter = new ArrayAdapter< DataHoldingClass>(context, android.R.layout.simple_dropdown_item_1line, info);` 

And the finale:

 `@Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { Log.d(" arg2 ="+arg2+" arg3="+arg3+" Real id ="+((DataHoldingClass)arg0.getAdapter().getItem(arg2)).getDataId(),""); } 

It worked for me. I hope I helped you.

0
source

Source: https://habr.com/ru/post/1305200/


All Articles