在搜索后单击RecyclerView不会产生正确的数据

时间:2018-02-08 18:37:05

标签: android android-recyclerview searchview recycler-adapter

我有一个片段,显示RecyclerView上的酒店列表。仅显示酒店名称。如果单击其中一个名称,将启动一个活动,其中显示酒店详细信息(姓名,地址,位置,房间数)。为了让生活更轻松,我还有一个SearchView,因此用户只需搜索酒店名称而不是滚动。

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);
}

显示初始列表和搜索很好。到目前为止没问题。问题是搜索后点击酒店。

说最初的酒店列表是:

  

{&#34; Hotel Foobar&#34;,&#34; Hotel California&#34;,&#34; Hotel 2112&#34;,&#34; Hotel Crimson&#34;}

如果我搜索&#34; 2112&#34;,RecyclerView将仅显示&#34; Hotel 2112&#34; (这是正确的),但点击它将显示&#34; Hotel Foobar&#34;的详细信息。我想这是因为

Hotel hotel = hotelList.get(position);

位置为0。

如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

不要将列表与所有酒店一起使用,请尝试使用当前正在使用的列表。

hotelAdapter.hotelList_filtered.get(position);

答案 1 :(得分:0)

重新说这个,我也在我的项目中使用了同样的东西,我使用如下,它给出了正确的结果

 @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();

}

您从过滤器列表中获取数据,因此没有此问题

 @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 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;
    }