warfo09
warfo09

Reputation: 157

RecyclerView position on filter

I have a RecyclerView which displays CardView with a bunch of info from SQLite database, such as address, lat, long, etc. When I introduce a filter in activity to search by address_name, it doesn't quite filter correctly. It does filter by address_name, but the rest of the information, such as lat long etc. is being displayed from the first item in the list, rather than the one that should correspond to address_name.

I tried doing the following (you will see it in the onClickListener), however it doesn't help too:

int adapterPosition = holder.getAdapterPosition();

Any ideas how to display the position correctly? Code Below. Thank you!!!

SavedActivity.java

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

    @Override
    public boolean onQueryTextChange(String newText) {
        String input = newText.toLowerCase();
        ArrayList<String> newList = new ArrayList<>();
        for (String addressname : DBaddress_name) {
            if (addressname.toLowerCase().contains(input)) {
                newList.add(addressname);
            }
        }
        customerAdapter.updateList(newList);
        return true;
    }
}

CustomAdapter.java

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

    private Context context;
    private Activity activity;
    private ArrayList<String> address_id, address_timestamp, address, address_lat, address_long, address_name;

    private Animation recycler_anim;

    CustomAdapter(Activity activity, Context context, ArrayList address_id, ArrayList address_timestamp, ArrayList address, ArrayList address_lat, ArrayList address_long, ArrayList address_name)

    {
        this.activity = activity;
        this.context = context;
        this.address_id = address_id;
        this.address_timestamp = address_timestamp;
        this.address = address;
        this.address_lat = address_lat;
        this.address_long = address_long;
        this.address_name = address_name;
    }
    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.my_row, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder holder, final int position) {

        holder.address_id_txt.setText("Nº" + String.valueOf(address_id.get(position)));
        holder.address_timestamp_txt.setText(String.valueOf(address_timestamp.get(position)));
        holder.address_txt.setText(String.valueOf(address.get(position)));
        holder.address_lat_txt.setText("Lat: " + String.valueOf(address_lat.get(position)));
        holder.address_long_txt.setText("Long: " + String.valueOf(address_long.get(position)));
        holder.address_name_txt.setText(String.valueOf(address_name.get(position)));
        holder.recyclerViewLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int adapterPosition = holder.getAdapterPosition();
                Intent intent = new Intent(context, UpdateActivity.class);
                intent.putExtra("id",String.valueOf(address_id.get(adapterPosition)));
                intent.putExtra("address",String.valueOf(address.get(adapterPosition)));
                intent.putExtra("address_name",String.valueOf(address_name.get(adapterPosition)));
                activity.startActivityForResult(intent, 1);
            }
        });
    }

    @Override
    public int getItemCount() {
        return address_name.size(); //size method of any of the array - all the same
    }


    public class MyViewHolder extends RecyclerView.ViewHolder {

        TextView address_id_txt, address_timestamp_txt, address_txt, address_lat_txt, address_long_txt, address_name_txt, address_distance_txt;
        LinearLayout recyclerViewLayout;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            address_id_txt = itemView.findViewById(R.id.address_id_txt);
            address_timestamp_txt = itemView.findViewById(R.id.address_timestamp_txt);
            address_txt = itemView.findViewById(R.id.address_address_txt);
            address_lat_txt = itemView.findViewById(R.id.address_lat_txt);
            address_long_txt = itemView.findViewById(R.id.address_long_txt);
            address_name_txt = itemView.findViewById(R.id.address_name_txt);
            address_distance_txt = itemView.findViewById(R.id.address_distance_txt);
            recyclerViewLayout = itemView.findViewById(R.id.recyclerViewLayout);
                        //Animate RecyclerView
            recycler_anim = AnimationUtils.loadAnimation(context, R.anim.recycler_anim);
            recyclerViewLayout.setAnimation(recycler_anim);
        }
    }
    public void updateList(ArrayList<String> newList){
        address_name = new ArrayList<>();
        address_name.addAll(newList);
        notifyDataSetChanged();

    }
}

Upvotes: 1

Views: 68

Answers (2)

Zain
Zain

Reputation: 40830

You need to create a POJO class that holds fields for the data you want to display in each RecyclerView item; and instead of passing in different lists to the adapter, you can just pass in a single list of this POJO to the RecyclerView; this will reflect any filtration correctly as all the lists are consolidated into a single list.

So, you've to replace the below

private ArrayList<String> address_id, address_timestamp, address, address_lat, address_long, address_name;

With

private ArrayList<MyPojo> items;

and MyPojo class should have the address_Id, address_timestamp, long, lat, address_name fields with setters and getters.

UPDATE: not quite sure how to filter still?

You just need to migrate Strings to MyPojo instances, so for filtration purpose you need to create a list of MyPojo not list of Strings, and the adapter has to have MyPojo list as well.

@Override
public boolean onQueryTextChange(String newText) {
    String input = newText.toLowerCase();
    // ArrayList<String> newList = new ArrayList<>();
    ArrayList<MyPojo> newList = new ArrayList<>();
    
    for (MyPojo pojo : myPojoList) {
        if (pojo.getAddressName().toLowerCase().contains(input)) {
            newList.add(pojo);
        }
    }
    customerAdapter.updateList(newList); // should accept MyPojo as a paramter not a String
    return true;
}

Upvotes: 1

Golam ShaQib
Golam ShaQib

Reputation: 11

You are just passing the address_name and updating this List inside your adapter, that's why the other values are not getting updated, You have to passs other Lists as well to update them properly.

Upvotes: 1

Related Questions