【问题标题】:How to get original item position after filter in Android RecyclerView adapter?如何在 Android RecyclerView 适配器中过滤后获取原始项目位置?
【发布时间】:2017-01-28 16:19:54
【问题描述】:

我在 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


【解决方案1】:

使用此代码:

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 这里的问题是,对于在 onBindViewHolder() 中膨胀的每一行,您将拥有一个新的单击侦听器实例,这可能会影响性能。
    【解决方案3】:

    旧职位:

     @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&lt;?&gt; 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);
    
                }
            });
    

    【讨论】:

      猜你喜欢
      • 2021-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多