Search code examples
android-recyclerviewpositionsyntax-errorsearchviewandroid-viewholder

Configure Search View on Recycler View


When I search something in my app the Text of the searched item is changed because the search changes it's position...

The OnBindViewHolder of my adapter configure that the "setText" should set in a position, but when I Search something, the position of the searched item in Recycler View is changed to the first item, so the setText changed his text for the first item text.

The error

the text "receita torta" changing to "receita pudim":
the text "receita torta" changing to "receita pudim" 1: https://i.sstatic.net/F5CzW.gif

Adapter

public class AdapterLanches extends RecyclerView.Adapter<AdapterLanches.MyViewHolder> implements Filterable {

private List<Lanches> listaLanches;
private List<Lanches> listaLanchesCompleta;

int estadoPrograma;

public class MyViewHolder extends RecyclerView.ViewHolder {

    TextView titulo;

    public MyViewHolder(@NonNull View itemView) {
        super(itemView);

        titulo = itemView.findViewById(R.id.textnomeLancheId);

    }
}


public AdapterLanches(List<Lanches> listaLanches) {
    this.listaLanches = listaLanches;
    listaLanchesCompleta = new ArrayList<>(listaLanches);

}



@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View itemListaLanches = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_lanches, parent, false);

    return new MyViewHolder(itemListaLanches);
}

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
    Lanches itemAtual = listaLanches.get(position);
    
    holder.titulo.setText(itemAtual.getTitulo());


}

@Override
public int getItemCount() {

    return listaLanches.size();
}



@Override
public Filter getFilter() {
    return lanchesFilter;
}

private Filter lanchesFilter = new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        List<Lanches> filteredList = new ArrayList<>();
        if (constraint == null || constraint.length() == 0){
            filteredList.addAll(listaLanchesCompleta);
        }else{
            estadoPrograma = 1;
            String filterPattern = constraint.toString().toLowerCase().trim();

            for ( Lanches item : listaLanchesCompleta){
                if (item.getTitulo().toLowerCase().contains(filterPattern)){
                    filteredList.add(item);
                }
            }
        }
        FilterResults results = new FilterResults();
        results.values = filteredList;

        return results;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        listaLanches.clear();
        listaLanches.addAll( (List) results.values);
        notifyDataSetChanged();

    }
};

}

Search Menu on Lanches Activity

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_lanches, menu);
    MenuItem searchItem = menu.findItem(R.id.pesquisaIcone);
    SearchView searchView = (SearchView) searchItem.getActionView();

    searchView.setImeOptions(EditorInfo.IME_ACTION_DONE);


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

        @Override
        public boolean onQueryTextChange(String newText) {
            AdapterLanches adapterLanches = new AdapterLanches(listaLanches);
            adapterLanches.getFilter().filter(newText);
            return false;
        }
    });
    return true;
}

}


Solution

  • This is error is happening because you are not using the same reference for your Adapter class.

    @Override
            public boolean onQueryTextChange(String newText) {
                AdapterLanches adapterLanches = new AdapterLanches(listaLanches);
                adapterLanches.getFilter().filter(newText);
                return false;
            }
    

    in this method you should use the same reference as before, when you submitted your list to the RecyclerView, also the method should return true.

    Boa sorte amigo!