Reputation: 6763
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
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
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