Search code examples
androidlistviewlistview-adapterandroid-filterable

ListView custom filter with search box gives wrong item selected when filtered


I have a listview getting filtered by an edit text on top. However when i click on the item searched i get the result of another data being selected.

For instance, my list contains A, B, C. When I want to search the list for things starting with B, I will get B, but when I click B, it returns me A.

public class InformationActivity extends AppCompatActivity {
    private ArrayList<Actors> actorsList;
    private ActorAdapter adapter;
    private String strId[],strNama[],strDeskripsi[],strFoto[],strMarker[],strLng[],strLat[];

    private EditText et;
    int textlength = 0;
    private ArrayList<Actors> array_sort= new ArrayList<Actors>();

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

        actorsList = new ArrayList<Actors>();

        registerReceiver(mNetworkReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));

        et = (EditText) findViewById(R.id.EditText01);

        final ListView listview = (ListView)findViewById(R.id.list);
        adapter = new ActorAdapter(getApplicationContext(), R.layout.row, actorsList);
        listview.setAdapter(adapter);

        listview.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
                // TODO Auto-generated method stub
                String daftarId = strId[position], daftarNama = strNama[position], daftarDeskripsi = strDeskripsi[position], daftarFoto = strFoto[position], daftarMarker = strMarker[position], daftarLng = strLng[position], daftarLat = strLat[position];
                Intent i = new Intent(InformationActivity.this,Detail_Activity.class);
                i.putExtra("id",daftarId);
                i.putExtra("nama",daftarNama);
                i.putExtra("deskripsi",daftarDeskripsi);
                i.putExtra("foto",daftarFoto);
                i.putExtra("marker",daftarMarker);
                i.putExtra("lng",daftarLng);
                i.putExtra("lat",daftarLat);
                startActivity(i);
            }
        });

        et.addTextChangedListener(new TextWatcher()
        {
            public void afterTextChanged(Editable s)
            {
                // Abstract Method of TextWatcher Interface.
            }
            public void beforeTextChanged(CharSequence s,
                                          int start, int count, int after)
            {
                // Abstract Method of TextWatcher Interface.
            }
            public void onTextChanged(CharSequence s,
                                      int start, int before, int count)
            {
                textlength = et.getText().length();
                array_sort.clear();
                for (int i = 0; i < actorsList.size(); i++)
                {
                    String nama = actorsList.get(i).getName();
                    if (textlength <= nama.length())
                    {
                        if (et.getText().toString().equalsIgnoreCase( (String) nama.subSequence(0,textlength) ) )
                        {
                            array_sort.add(actorsList.get(i));
                        }
                    }
                }

                adapter = new ActorAdapter(getApplicationContext(), R.layout.row, array_sort);
                listview.setAdapter(adapter);
            }
        });
    }

    class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {

        ProgressDialog dialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            dialog = new ProgressDialog(InformationActivity.this);
            dialog.setMessage("Silahkan tunggu");
            dialog.setTitle("Mendapatkan data...");
            dialog.show();
            dialog.setCancelable(true);
        }

        @Override
        protected Boolean doInBackground(String... urls) {
            try {
                HttpGet httppost = new HttpGet(urls[0]);
                HttpClient httpclient = new DefaultHttpClient();
                HttpResponse response = httpclient.execute(httppost);
                int status = response.getStatusLine().getStatusCode();
                if (status == 200) {
                    HttpEntity entity = response.getEntity();
                    String data = EntityUtils.toString(entity);
                    JSONObject jsono = new JSONObject(data);
                    JSONArray konten = jsono.getJSONArray("konten");
                    strId = new String[konten.length()];
                    strNama = new String[konten.length()];
                    strDeskripsi = new String[konten.length()];
                    strFoto = new String[konten.length()];
                    strMarker = new String[konten.length()];
                    strLng = new String[konten.length()];
                    strLat = new String[konten.length()];
                    for (int i = 0; i < konten.length(); i++) {
                        JSONObject object = konten.getJSONObject(i);
                        strId[i] = object.getString("id");
                        strNama[i] = object.getString("nama");
                        strDeskripsi[i] = object.getString("deskripsi");
                        strFoto[i] = object.getString("foto");
                        strMarker[i] = object.getString("marker");
                        strLng[i] = object.getString("lng");
                        strLat[i] = object.getString("lat");
                        Actors actor = new Actors();
                        actor.setName(strNama[i]);
                        actor.setImage(strFoto[i]);
                        actorsList.add(actor);
                    }
                    return true;
                }

            } catch (ParseException e1) {
                e1.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return false;
        }

        protected void onPostExecute(Boolean result) {
            dialog.cancel();
            adapter.notifyDataSetChanged();
            if(!result) {
                Toast.makeText(getApplicationContext(), "Tidak dapat mengambil data dari server, silahkan cek koneksi internet anda", Toast.LENGTH_LONG).show();
            }
        }
    }
}

My adapter

    public class ActorAdapter extends ArrayAdapter<Actors> {
        private ArrayList<Actors> actorList;
        private LayoutInflater vi;
        private int Resource;
        private ViewHolder holder;

        public ActorAdapter(Context context, int resource, ArrayList<Actors> objects) {
            super(context, resource, objects);
            vi = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            Resource = resource;
            actorList = objects;
        }


        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
             View v = convertView;
            if (v == null) {
                holder = new ViewHolder();
                v = vi.inflate(Resource, null);
                holder.imageview = (ImageView) v.findViewById(R.id.imgIcon);
                holder.tvName = (TextView) v.findViewById(R.id.nama);
                v.setTag(holder);
            } else {
                holder = (ViewHolder) v.getTag();
            }
            holder.tvName.setText(actorList.get(position).getName());
            Picasso.with(this.getContext()).load(actorList.get(position).getImage()).placeholder(R.layout.progress).resize(110,110).error(R.mipmap.error).into(holder.imageview);
            return v;
        }

        static class ViewHolder {
            public ImageView imageview;
            public TextView tvName;
        }
    }

My Actors Class

    public class Actors {
            private String name;
            private String image;
            public Actors(String name, String description, String image, String id) {
                this.name = name;
                this.image = image;
            }


            public Actors() {
                // TODO Auto-generated constructor stub
            }

            public String getImage() {
                return image;
            }

            public String getName() {
                return name;
            }

            public void setImage(String image) {
                this.image = image;
            }

            public void setName(String name) {
                this.name = name;
            }

        }

My Actors class

    public class Actors {
    private String name;
    private String image;
    public Actors(String name, String description, String image, String id) {
        this.name = name;
        this.image = image;
    }


    public Actors() {
        // TODO Auto-generated constructor stub
    }

    public String getImage() {
        return image;
    }

    public String getName() {
        return name;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Solution

  • The reason for getting wrong value is at first you load the entire datas in listview.When you filter the datas based on text.you use an another arraylist and update it to adapter.When you click on listview you trying to get values from full list datas instead of filterlist.so that you are getting wrong values.

    let's do some changes in code:

    In InformationActivity class remove the String arrays namely

    strId[],strNama[],strDeskripsi[],strFoto[],strMarker[],strLng[],strLat[];
    

    initialize arraylist inside oncreate like this

    array_sort= new ArrayList<Actors>(); 
    

    pass array_sort list to adapter instead of actorsList.

         adapter = new ActorAdapter(getApplicationContext(), R.layout.row, array_sort);
        listview.setAdapter(adapter);
    

    replace this code in listview.setOnItemClickListener

       listview.setOnItemClickListener(new OnItemClickListener() {
    
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int position, long id) {
                // TODO Auto-generated method stub
    
                Intent i = new Intent(InformationActivity.this,Detail_Activity.class);
                i.putExtra("id",array_sort.get(position).getId());
                i.putExtra("nama",array_sort.get(position).getName());
                i.putExtra("deskripsi",array_sort.get(position).getDeskripsi());
                i.putExtra("foto",array_sort.get(position).getImage());
                i.putExtra("marker",array_sort.get(position).getMarker());
                i.putExtra("lng",array_sort.get(position).getLng());
                i.putExtra("lat",array_sort.get(position).getLat());
                startActivity(i);
            }
        });
    

    In JSONAsyncTask class use this code instead of your code:

              if (status == 200) {
                    HttpEntity entity = response.getEntity();
                    String data = EntityUtils.toString(entity);
                    JSONObject jsono = new JSONObject(data);
                    JSONArray konten = jsono.getJSONArray("konten");
    
                    for (int i = 0; i < konten.length(); i++) {
                        JSONObject object = konten.getJSONObject(i);
                         Actors actors=new Actors();
                         actors.setId(object.getString("id"));
                        actors.setName(object.getString("nama"));
                       actors.setDeskripsi(object.getString("deskripsi"));
                         actors.setImage(object.getString("foto"));
                         actors.setMarker(object.getString("marker"));
                         actors.setLng(object.getString("lng"));
                        actors.setLat(object.getString("lat"));
    
                        actorsList.add(actors);
                         array_sort.add(actors);
                    }
                    return true;
                }
    

    Finally make your Actors Object class as like this.

    public class Actors {
    
    private String id;
    private String name;
    private String deskripsi;
    private String image;
    private String marker;
    private String lng;
    private String lat;
    
    
    public Actors(String id, String name, String deskripsi, String image, String marker, String lng, String lat) {
        this.id = id;
        this.name = name;
        this.deskripsi = deskripsi;
        this.image = image;
        this.marker = marker;
        this.lng = lng;
        this.lat = lat;
    }
    
    public Actors() {
        // TODO Auto-generated constructor stub
    }
    
    public String getImage() {
        return image;
    }
    
    public String getName() {
        return name;
    }
    
    public void setImage(String image) {
        this.image = image;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public String getDeskripsi() {
        return deskripsi;
    }
    
    public void setDeskripsi(String deskripsi) {
        this.deskripsi = deskripsi;
    }
    
    public String getMarker() {
        return marker;
    }
    
    public void setMarker(String marker) {
        this.marker = marker;
    }
    
    public String getLng() {
        return lng;
    }
    
    public void setLng(String lng) {
        this.lng = lng;
    }
    
    public String getLat() {
        return lat;
    }
    
    public void setLat(String lat) {
        this.lat = lat;
    }
    }