How to get original item position after filter in Android RecyclerView adapter?

I have implement filter in android recyclerview adapter. But problem is that when I filtered item than position of item changed. I need the original position of the item after filter? How can i get it?

Here is my code:

public class SearchAdapter extends SelectableAdapter<SearchAdapter.ViewHolder> implements Filterable {

    static ArrayList<SingleHadishDisplayModel> singleHadishDisplayModels;
    ArrayList<SingleHadishDisplayModel> singleHadishDisplayModelsFilter;
    public ViewHolder.ClickListener clickListener;

    Context context;

    public SearchAdapter(ArrayList<SingleHadishDisplayModel> singleHadishDisplayModels) {
        this.singleHadishDisplayModelsFilter = singleHadishDisplayModels;
        if (singleHadishDisplayModels != null) {
            this.singleHadishDisplayModels = new ArrayList<>(singleHadishDisplayModels);
        } else {
            this.singleHadishDisplayModels = null;
        }
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        context = parent.getContext();
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.search_adapter, parent, false);

        ViewHolder vh = new ViewHolder(v, clickListener);
        return vh;
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        holder.topic.setText(singleHadishDisplayModelsFilter.get(position).topic);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Contants.clickPos=position;
                /*long id =  SearchAdapter.getItemId(position);
                Toast.makeText(context,Long.toString(id), Toast.LENGTH_SHORT).show();*/

                Intent intent = new Intent(context, HadishDetails.class);
                context.startActivity(intent);
            }
        });
    }

    @Override
    public int getItemCount() {
        return singleHadishDisplayModelsFilter.size();
    }

    public long getItemId(int position) {
        int itemID;
        // orig will be null only if we haven't filtered yet:
        if (singleHadishDisplayModels == null) {
            itemID = position;
        } else {
            itemID = singleHadishDisplayModels.indexOf(singleHadishDisplayModels.get(position));
        }
        return itemID;
    }


    @Override
    public Filter getFilter() {
        Filter filter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults filterResults = new FilterResults();

                if (constraint.length() == 0) {
                    filterResults.values = SearchAdapter.this.singleHadishDisplayModels;
                    return filterResults;
                }

                String searchString = constraint.toString().toLowerCase();

                List<SingleHadishDisplayModel> filteredList = new ArrayList<>();
                filterResults.values = filteredList;

                for (SingleHadishDisplayModel tableSelectionDTO : SearchAdapter.this.singleHadishDisplayModels) {
                    if (tableSelectionDTO.topic.toLowerCase().contains(searchString)) {
                        filteredList.add(tableSelectionDTO);
                    }
                }

                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                SearchAdapter.this.singleHadishDisplayModelsFilter = (ArrayList<SingleHadishDisplayModel>) results.values;
                SearchAdapter.this.notifyDataSetChanged();
            }
        };

        return filter;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
        TextView topic;

        private ClickListener listener;

        public ViewHolder(View itemView, ClickListener clickListener) {
            super(itemView);

            this.listener = clickListener;
            topic = (TextView) itemView.findViewById(R.id.topic_search);

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

        @Override
        public void onClick(View v) {
            if (listener != null) {
                listener.onItemClicked(getAdapterPosition());
            }
        }

        @Override
        public boolean onLongClick(View view) {
            if (listener != null) {
                return listener.onItemLongClicked(getAdapterPosition());
            }
            return false;
        }

        public interface ClickListener {
            public void onItemClicked(int position);

            public boolean onItemLongClicked(int position);
        }

    }
}

My activity:

public class SearchActivity extends AppCompatActivity implements SearchAdapter.ViewHolder.ClickListener {
    private RecyclerView mRecyclerView;
    public SearchAdapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    ArrayList<SingleHadishDisplayModel> singleHadishDisplayModels;
    SingleHadishDisplayModel singleHadishDisplayModel;
    int positionClick;
    public static final String POST_ID = "postID";

    FloatingSearchView floatingSearchView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_search);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //floatingSearchView= (FloatingSearchView) findViewById(R.id.floating_search_view);
        singleHadishDisplayModels = new ArrayList<SingleHadishDisplayModel>();
        singleHadishDisplayModels = Contants.singleHadishDisplayModelsSaved;

        mRecyclerView = (RecyclerView) findViewById(R.id.search_reycler);
        mRecyclerView.setHasFixedSize(true);
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);

        mAdapter = new SearchAdapter(singleHadishDisplayModels);
        mRecyclerView.setAdapter(mAdapter);


        /*  floatingSearchView.setOnQueryChangeListener(new FloatingSearchView.OnQueryChangeListener() {
        @Override
        public void onSearchTextChanged(String oldQuery, final String newQuery) {
        mAdapter.clearSelection();
        mAdapter.getFilter().filter(newQuery);
    }
});*/

        EditText et = (EditText) findViewById(R.id.search_et);
        et.addTextChangedListener(new TextWatcher() {

            public void onTextChanged(CharSequence cs, int arg1, int arg2,
                                      int arg3) {
                // When user changed the Text
                SearchActivity.this.mAdapter.getFilter().filter(cs);
                Toast.makeText(SearchActivity.this, Integer.toString(arg1), Toast.LENGTH_SHORT).show();
            }

            public void beforeTextChanged(CharSequence arg0, int arg1,
                                          int arg2, int arg3) {
                // TODO Auto-generated method stub

            }

            public void afterTextChange(Editable arg0) {
                // TODO Auto-generated method stub

            }

            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub

            }
        });


    }


    @Override
    public void onItemClicked(int position) {
        positionClick = position;


        // Intent intent =new Intent(SearchActivity.this,HadishDetails.class);
        //startActivity(intent);

        //  Contants.clickPos=position;

    }

    @Override
    public boolean onItemLongClicked(int position) {
        return false;
    }
}
Enquirer: arif

||

Solution #1:

Use This Codes :

int pos = list.indexOf(arraylist1.get(getAdapterPosition()));

Here list is the original list and arrayList is filtered items list.

Respondent: murtaza agaz

Solution #2:

Try this code..
make interface into adapter for handling click event like this way..

    OnItemClick onItemClick;

public void setOnItemClick(OnItemClick onItemClick) {
    this.onItemClick = onItemClick;
}

public interface OnItemClick {
    void getPosition(String data); //pass any data to shared it.
}

bindview method changes..

@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    holder.topic.setText(singleHadishDisplayModelsFilter.get(position).topic);
    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            // Contants.clickPos=position;
            /*long id =  SearchAdapter.getItemId(position);
            Toast.makeText(context,Long.toString(id), Toast.LENGTH_SHORT).show();*/
            onItemClick.getPosition("your data");
           // Intent intent = new Intent(context, HadishDetails.class);
           // context.startActivity(intent);
        }
       });
       }

after adapter bind into recycler view call below code..

        adpater.setOnItemClick(new RecyclerViewAdpater.OnItemClick() {
        @Override
        public void getPosition(String data) {
            // hear update your value for check into if condition.
            Intent intent = new Intent(context, HadishDetails.class);
            context.startActivity(intent);
            adpater.notifyDataSetChanged();
        }
    });
Respondent: Android Team

Solution #3:

old position :

 @Override
    public long getItemId(int position) {

        int itemID;
     
        // mOriginalValues will be null only if we haven't filtered yet:
        if (mOriginalValues == null)
        {
            itemID = position;
        
        }
        else
        {
            itemID = mOriginalValues.indexOf(mObjects.get(position));
           
        }
        return itemID;
     
    }

Here, mOriginalValues is the list after filtering, mObjects is the old list which was passed to the adapter, so when click on the list in onItemClick(AdapterView<?> adapterView, View view, int position, long l) the old position is :

int oldPositionAfterFilter = (int) mainAdapter.getItemId(position); 

so, always the real position even after filtering :

mainListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position , long l) {
                
                // always the real position even after filtering : 
                int oldPosition = (int) mainAdapter.getItemId(position); 

                String filePath = bs_filePathList.get(oldPosition);// always the original string; 
                bs_fileOptions(filePath);

            }
        });
Respondent: Noor Hossain

The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Leave a Reply

Your email address will not be published.