如何在Android RecyclerView适配器中过滤后获取原始项目位置?

问题描述 投票:0回答:4

我在 android recyclerview 适配器中实现了过滤器。但问题是,当我过滤项目时,项目的位置发生了变化。我需要过滤后项目的原始位置?我怎样才能得到它?

这是我的代码:

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

    }
}

我的活动:

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;
    }
}
android android-recyclerview android-filter
4个回答
4
投票

使用此代码:

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

这里

list
是原始列表,
arrayList
是过滤后的项目列表。


0
投票

试试这个代码.. 将接口制作成适配器来像这样处理点击事件..

    OnItemClick onItemClick;

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

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

bindview 方法更改..

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

适配器绑定到回收器视图后调用下面的代码..

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

0
投票

旧位置:

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

这里,

mOriginalValues
是过滤后的列表,
mObjects
是传递给适配器的旧列表,所以当点击
onItemClick(AdapterView<?> adapterView, View view, int position, long l)
中的列表时,旧位置是:

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

所以,即使在过滤之后,也始终是真实位置:

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

            }
        });

0
投票

这是您获取所选项目索引的最简单答案:

int pos = items.indexOf(adapter.getItem(position)));
© www.soinside.com 2019 - 2024. All rights reserved.