Search code examples
androidandroid-recyclerviewsearchview

How to get the correct item when the SearchView filters result display in the RecyclerView


enter image description hereI have aRecyclerView and a SearchView in my Activity .. the SearchView updates the RecyclerView as expected by filtering the RecyclerView but the get(position) is not updating and the RecyclerView onClick triggers the first item in the list if i click the first listitem after the results are filtered..

My Activity is as follows:

public class MangalStuti extends AppCompatActivity implements SearchView.OnQueryTextListener {
private List<Name> movieList = new ArrayList<>();
private RecyclerView recyclerView;
 //  EditText editTextSearch;
//  ArrayList<String> names;
private Adapter mAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.mangal_stuti_activity);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
   // editTextSearch = (EditText) findViewById(R.id.editTextSearch);

    mAdapter = new Adapter(movieList);
    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
    recyclerView.setLayoutManager(mLayoutManager);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setAdapter(mAdapter);


    // row click listener
    recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new RecyclerTouchListener.ClickListener() {

        @Override
        public void onClick(View view, int position) {
            Name name = movieList.get(position);
            String text = name.getTitle();
            Toast.makeText(getApplicationContext(), text + " is selected!", Toast.LENGTH_SHORT).show();
            if (text == "Apple"){
                view.getContext().startActivity(new Intent(view.getContext(),Apple.class));
            }
            if (text == "Tiger"){
                view.getContext().startActivity(new Intent(view.getContext(),Animal.class));
            }
        }

        @Override
        public void onLongClick(View view, int position) {

        }
    }));

    prepareMovieData();
}

private void prepareMovieData() {
    Name movie = new Name("Apple", "Fruit", "2018");
    movieList.add(movie);

    movie = new Name("Tiger", "Animal", "2018");
    movieList.add(movie);

    movie = new Name("Paris", "Place", "2018");
    movieList.add(movie);



    mAdapter.notifyDataSetChanged();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu,menu);
    MenuItem menuItem=menu.findItem(R.id.actionsearch);
    SearchView searchView=(SearchView) MenuItemCompat.getActionView(menuItem);
    searchView.setOnQueryTextListener(this);
    return super.onCreateOptionsMenu(menu);
}


@Override
public boolean onQueryTextSubmit(String query) {
    return false;
}

@Override
public boolean onQueryTextChange(String newText) {
    newText=newText.toLowerCase();
    ArrayList<Name> newlist=new ArrayList<>();
    for(Name name:movieList)
    {
        String getName=name.getTitle().toLowerCase();
        if(getName.contains(newText)){
            newlist.add(name);

        }
    }
    mAdapter.filter(newlist);
    return true;
}
}

My Adapter class

public class Adapter extends RecyclerView.Adapter <Adapter.MyViewHolder>{

private List<Name> movieList;
private ArrayList<Name> arraylist;

public class MyViewHolder extends RecyclerView.ViewHolder {
    public TextView title, year, genre;

    public MyViewHolder(View view) {
        super(view);
        title = (TextView) view.findViewById(R.id.title);
        genre = (TextView) view.findViewById(R.id.genre);
        year = (TextView) view.findViewById(R.id.year);
    }

}

public Adapter(List<Name> movieList) {
    this.movieList = movieList;
    this.arraylist = new ArrayList<Name>();
    this.arraylist.addAll(movieList);
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view= LayoutInflater.from(parent.getContext()).inflate(R.layout.movie_list_row,parent,false);
    return new MyViewHolder(view);
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
    Name name = movieList.get(position);
    holder.title.setText(name.getTitle());
    holder.genre.setText(name.getGenre());
    holder.year.setText(name.getYear());

}

@Override
public int getItemCount() {
    return movieList.size();
}

public void filter(ArrayList<Name> newList)
{
    movieList=new ArrayList<>();
    movieList.addAll(newList);
    notifyDataSetChanged();
}
}

Name Class

public class Name {
private String title, genre, year;

public Name() {
}

public Name(String title, String genre, String year) {
    this.title = title;
    this.genre = genre;
    this.year = year;
}

public String getTitle() {
    return title;

}

public void setTitle(String name) {
    this.title = name;

}

public String getYear() {
    return year;

}

public void setYear(String year) {
    this.year = year;

}

public String getGenre() {
    return genre;

}

public void setGenre(String genre) {
    this.genre = genre;

}
}

Solution

  • Create a method in adapter class like below

    public List<Name> getMovieList(){
      return movieList;
    }
    

    Then use below code to get the selected movie

     // row click listener
        recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new RecyclerTouchListener.ClickListener() {
    
            @Override
            public void onClick(View view, int position) {
                Name name = mAdapter.getMovieList().get(position); // Important one
                String text = name.getTitle();
                Toast.makeText(getApplicationContext(), text + " is selected!", Toast.LENGTH_SHORT).show();
                if (text == "Apple"){
                    view.getContext().startActivity(new Intent(view.getContext(),Apple.class));
                }
                if (text == "Tiger"){
                    view.getContext().startActivity(new Intent(view.getContext(),Animal.class));
                }
            }
    
            @Override
            public void onLongClick(View view, int position) {
    
            }
        }));