javaandroidarraylistandroid-arrayadaptercustom-arrayadapter

Android ArrayList search filter changing index when using OnItemCLick


This is a weird problem, almost seems like a bug. So i am using an arraylist and a customlistview that extends ArrayAdapter.

arraylist populates the customlistview, i implemented a search box in the actionbar that filters the custom adapter, which works fine by the way.

The problem is i am trying to use the filtered data so i am using OnItemCLickListener on the listview to use the index and grab the data corresponding to the filtered result.

But what is happening here is data is getting filtered and so is the arraylist itself.

say when i open the activity it shows me contacts all my contacts so i use the searchbar to search a name which gives me that name

say paul,

now paul is at 0 index after search bar filtering now when i click on paul i expect paul's data but i get the data of the arraylist's original 0 index data

say it was anil

so inside OniItelClickListiner i am getting anil's data insted of paul's

here is the code

public class sendSms extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {

    ListView listView;
    ArrayList<contact> arrayList;
    CustomArrayAdapterForContact customArrayAdapterForContact;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_send_sms);

        listView = (ListView) findViewById(R.id.showContactsListView);

        arrayList = new ArrayList<contact>();
        customArrayAdapterForContact = new CustomArrayAdapterForContact(this, arrayList);
        listView.setAdapter(customArrayAdapterForContact);

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent intent = new Intent(getApplicationContext(), typeMessage.class);

                intent.putExtra("id", arrayList.get(position).contact_id);
                intent.putExtra("name", arrayList.get(position).display_name);
                intent.putExtra("number", arrayList.get(position).display_number);

                startActivity(intent);
            }
        });

        getSupportLoaderManager().initLoader(5, null, this);
    }


    class CustomArrayAdapterForContact extends ArrayAdapter<contact> {


        ArrayList<contact> contact;

        public CustomArrayAdapterForContact(@NonNull Context context, ArrayList<contact> contact) {
            super(context, 0, contact);
            this.contact = contact;
        }

        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {

            contact innserContact = getItem(position);

            if (convertView == null){

                convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_layout, parent, false);

            }

            TextView username = (TextView) convertView.findViewById(R.id.subject);
            TextView userNumber = (TextView) convertView.findViewById(R.id.address);

            try {
                if (innserContact.display_name.length() > 30) {
                    username.setText(innserContact.display_name.substring(0, 30));
                }else{
                    username.setText(innserContact.display_name);
                }

                userNumber.setText(innserContact.display_number);
            }catch (Exception e){
                e.printStackTrace();
            }

            return convertView;

        }

    }

    @NonNull
    @Override
    public Loader<Cursor> onCreateLoader(int i, @Nullable Bundle bundle) {
        String[] projection = {
                ContactsContract.Contacts._ID,
                ContactsContract.Contacts.DISPLAY_NAME,
                ContactsContract.Contacts.HAS_PHONE_NUMBER
        };

        return new CursorLoader(
                this,
                ContactsContract.Contacts.CONTENT_URI,
                projection,
                null,
                null,
                ContactsContract.Contacts.DISPLAY_NAME
        );
    }

    @Override
    public void onLoadFinished(@NonNull Loader<Cursor> loader, Cursor cursor) {

        while(cursor.moveToNext()){

            String con_id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
            String con_name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));

            if (cursor.getInt(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)) > 0){
                ContentResolver cr = getContentResolver();
                Cursor pCur = cr.query(
                        ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                        null,
                        ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?",
                        new String[]{con_id}, null);

                while (pCur.moveToNext()) {

                    String phoneNo = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

                    contact con = new contact(con_id, con_name, phoneNo);
                    arrayList.add(con);

                    break;
                }
                pCur.close();
            }


        }
        customArrayAdapterForContact.notifyDataSetChanged();

    }

    @Override
    public void onLoaderReset(@NonNull Loader<Cursor> loader) {

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        MenuInflater inflater = getMenuInflater();

        inflater.inflate(R.menu.search_box, menu);

        MenuItem item = menu.findItem(R.id.app_bar_search);

        SearchView searchView = (SearchView)item.getActionView();

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {

                customArrayAdapterForContact.getFilter().filter(newText);

                return true;
            }
        });

        return super.onCreateOptionsMenu(menu);

    }


}

After the filtering

After the filtering

After clicking

After clicking


Solution

  • Note - not tested in project. Instead of

    intent.putExtra("id", arrayList.get(position).contact_id);
    intent.putExtra("name", arrayList.get(position).display_name);
    intent.putExtra("number", arrayList.get(position).display_number);
    

    try using

    intent.putExtra("id", parent.getItemAtPosition(position).contact_id);
    intent.putExtra("name", parent.getItemAtPosition(position).display_name);
    intent.putExtra("number", parent.getItemAtPosition(position).display_number);
    

    Also remember to cast fetched item to right type.