anta40
anta40

Reputation: 6763

Clicking on a RecyclerView after search doesn't yield correct data

I have a fragment which displays a list of hotels on a RecyclerView. Only the hotel names are displayed. If one of the names is clicked, an activity will launched, which displays the hotel detail (name, address, location, room count). To make life easier, I also have a SearchView, so user can simply search the hotel name instead of scrolling.

HotelFragment.java

public class HotelFragment extends Fragment {

    ArrayList<Kost> hotelList = new ArrayList<>();
    HotelAdapter mAdapter;
    SearchView searchView;

    public HotelFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.hotel_fragment, container, false);
        RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(layoutManager);
        hotelAdapter = new KostAdapter(mList);

        // if a hotel is clicked, launch an activity which displays its full information
        mAdapter.setOnItemClickListener(new ClickListener() {
            @Override
            public void onItemClick(int position, View v) {
                Hotel hotel = hotelList.get(position);
                Bundle bnd = new Bundle();
                bnd.putString("hotel_name", hotel.getName());
                bnd.putString("hotel_description", hotel.getDescription());
                bnd.putString("hotel_address", hotel.getAddress());
                bnd.putString("hotel_room", hotel.getRoom());
                bnd.putString("hotel_latitude", hotel.getLatitude());
                bnd.putString("hotel_longitude", hotel.getLongitude());

                Intent iii = new Intent(getActivity(), HotelDetailActivity.class);
                iii.putExtra("hotel_detail", bnd);

                startActivity(iii);
            }

            @Override
            public void onItemLongClick(int position, View v) {
            }
        });

        searchView = (SearchView) view.findViewById(R.id.searchView);
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {
                hotelAdapter.getFilter().filter(query);
                return false;
            }

            @Override
            public boolean onQueryTextChange(String query) {
                hotelAdapter.getFilter().filter(query);
                return false;
            }
        });

        hotelAdapter.notifyDataSetChanged();
        recyclerView.setAdapter(hotelAdapter);
        getHotelListFromFirebase();
        return view;
    }
}

HotelAdapter.java

public class HotelAdapter extends RecyclerView.Adapter<HotelAdapter.ViewHolder> implements Filterable {

    static ClickListener clickListener;
    ArrayList<Hotel> hotelList;
    ArrayList<Hotel> hotelList_filtered;

    public KostAdapter(ArrayList<Hotel> hotelList)
    {
        this.hotelList = hotelList;
        this.hotelList_filtered = hotelList;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list,parent,false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Hotel hotel = hotelList_filtered.get(position);
        holder.tvName.setText(hotel.getName());
        holder.tvDescription.setText(hotel.getDescription());
        holder.tvAddress.setText(hotel.getAddress());
    }

    @Override
    public int getItemCount() {
        if (hotelList_filtered != null) return hotelList_filtered.size();
        return 0;
    }

    public void setOnItemClickListener(ClickListener clickListener) {
        HotelAdapter.clickListener = clickListener;
    }

    @Override
    public Filter getFilter() {
        return new Filter(){
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                String sequence = charSequence.toString().toLowerCase();
                if (sequence.isEmpty()) kostList_filtered = kostList;
                else {
                    ArrayList<Hotel> filteredList = new ArrayList<>();
                    for (Hotel h : hotelList){
                        if (h.getName().toLowerCase().contains(sequence)){
                            filteredList.add(h);
                        }
                    }

                    hotelList_filtered = filteredList;
                }

                FilterResults filterResults = new FilterResults();
                filterResults.values = kostList_filtered;
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                hotelList_filtered = (ArrayList<Hotel>) filterResults.values;
                notifyDataSetChanged();
            }
        };
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener  {

        TextView tvName;
        TextView tvDescription;
        TextView tvAddressl

        public ViewHolder(View itemView)
        {
            super(itemView);
            tvName = (TextView) itemView.findViewById(R.id.tvName);
            tvDescription = (TextView) itemView.findViewById(R.id.tvDescription);
            tvAddress = (TextView) itemView.findViewById(R.id.tvAddress);

            itemView.setOnClickListener(this);
            itemView.setOnLongClickListener(this);
        }

        @Override
        public void onClick(View view) {
            clickListener.onItemClick(getAdapterPosition(), view);
        }

        @Override
        public boolean onLongClick(View view) {
            clickListener.onItemLongClick(getAdapterPosition(), view);
            return false;
        }
    }

}

ClickListener.java

public interface ClickListener {

    void onItemClick(int position, View v);
    void onItemLongClick(int position, View v);
}

Displaying the initial list and search are fine. No problem so far. The issue is clicking the hotel after search.

Say the initial hotel list is:

{"Hotel Foobar", "Hotel California", "Hotel 2112", "Hotel Crimson"}

If I search for "2112", the RecyclerView will only show "Hotel 2112" (which is correct), but clicking it will display the detail of "Hotel Foobar". I think this because

Hotel hotel = hotelList.get(position);

and position is 0.

How to fix this?

Upvotes: 0

Views: 244

Answers (2)

Abhishek kumar
Abhishek kumar

Reputation: 4445

Relpace this , I have also used same thing on my project i used as below its gives correct result

 @Override
    public int getItemCount() {
        if (hotelList_filtered != null) return hotelList_filtered.size();
        return 0;
    }

with,

 @Override
public int getItemCount() {
    if (hotelList_filtered != null) 
    return hotelList_filtered.size();

}

you are getting data from your filter list so no issue with this

 @Override
public void onBindViewHolder(ViewHolder holder, int position) {
    Hotel hotel = hotelList_filtered.get(position);
    holder.tvName.setText(hotel.getName());
    holder.tvDescription.setText(hotel.getDescription());
    holder.tvAddress.setText(hotel.getAddress());
}

Get position over here from your filterlist :

@Override
    public void onClick(View view) {
        clickListener.onItemClick(hotelList_filtered.get(getPosition()), view);
    }

    @Override
    public boolean onLongClick(View view) {
        clickListener.onItemLongClick(hotelList_filtered.get(getPosition()), view);
        return false;
    }

Upvotes: 0

destresa
destresa

Reputation: 117

Instead of using the list with all the hotels, try using the list that is currently being used.

hotelAdapter.hotelList_filtered.get(position);

Upvotes: 1

Related Questions