How do I get the position selected in a RecyclerView?

前端 未结 13 2420
自闭症患者
自闭症患者 2020-11-27 04:40

I am experimenting with the support library\'s recyclerview and cards. I have a recyclerview of cards. Each card has an \'x\' icon at the top right corner to remove it:

相关标签:
13条回答
  • 2020-11-27 04:57

    No need to have your ViewHolder implementing View.OnClickListener. You can get directly the clicked position by setting a click listener in the method onCreateViewHolder of RecyclerView.Adapter here is a sample of code :

    public class ItemListAdapterRecycler extends RecyclerView.Adapter<ItemViewHolder>
    {
    
        private final List<Item> items;
    
        public ItemListAdapterRecycler(List<Item> items)
        {
            this.items = items;
        }
    
        @Override
        public ItemViewHolder onCreateViewHolder(final ViewGroup parent, int viewType)
        {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row, parent, false);
    
            view.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View view)
                {
                    int currentPosition = getClickedPosition(view);
                    Log.d("DEBUG", "" + currentPosition);
                }
            });
    
            return new ItemViewHolder(view);
        }
    
        @Override
        public void onBindViewHolder(ItemViewHolder itemViewHolder, int position)
        {
            ...
        }
    
        @Override
        public int getItemCount()
        {
            return items.size();
        }
    
        private int getClickedPosition(View clickedView)
        {
            RecyclerView recyclerView = (RecyclerView) clickedView.getParent();
            ItemViewHolder currentViewHolder = (ItemViewHolder) recyclerView.getChildViewHolder(clickedView);
            return currentViewHolder.getAdapterPosition();
        }
    
    }
    
    0 讨论(0)
  • 2020-11-27 04:59

    Personally, the simplest way that I have found and works great for me is as follows:

    Create an interface inside your "RecycleAdapter" Class (Subclass)

    public interface ClickCallback {
        void onItemClick(int position);
    }
    

    Add a variable of the interface as a parameter in the Constructor.

    private String[] items;
    private ClickCallback callback;
    
    public RecyclerAdapter(String[] items, ClickCallback clickCallback) {
        this.items = items;
        this.callback = clickCallback;
    }
    

    Set a Click listener in the ViewHolder (another subclass) and pass the 'position' to through the interface

        AwesomeViewHolder(View itemView) {
            super(itemView);
            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    callback.onItemClick(getAdapterPosition());
                }
            });
            mTextView = (TextView) itemView.findViewById(R.id.mTextView);
        }
    

    Now, when initializing the recycler adapter in an activity/fragment, just Create a new 'ClickCallback' (interface)

    String[] values = {"Hello","World"};
    RecyclerAdapter recyclerAdapter = new RecyclerAdapter(values, new RecyclerAdapter.ClickCallback() {
        @Override
        public void onItemClick(int position) {
             // Do anything with the item position
        }
    });
    

    That's it for me. :)

    0 讨论(0)
  • 2020-11-27 05:02

    Set your onClickListeners on onBindViewHolder() and you can access the position from there. If you set them in your ViewHolder you won't know what position was clicked unless you also pass the position into the ViewHolder

    EDIT

    As pskink pointed out ViewHolder has a getPosition() so the way you were originally doing it was correct.

    When the view is clicked you can use getPosition() in your ViewHolder and it returns the position

    Update

    getPosition() is now deprecated and replaced with getAdapterPosition()

    Update 2020

    getAdapterPosition() is now deprecated and replaced with getAbsoluteAdapterPosition() or getBindingAdapterPosition()

    Kotlin code:

    override fun onBindViewHolder(holder: MyHolder, position: Int) {
            // - get element from your dataset at this position
            val item = myDataset.get(holder.absoluteAdapterPosition)
        }
    
    0 讨论(0)
  • 2020-11-27 05:04
     public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    
        FrameLayout root;
    
    
        public ViewHolder(View itemView) {
            super(itemView);
    
            root = (FrameLayout) itemView.findViewById(R.id.root);
            root.setOnClickListener(this);
        }
    
    
        @Override
        public void onClick(View v) {
            LogUtils.errorLog("POS_CLICKED: ",""+getAdapterPosition());
        }
    }
    
    0 讨论(0)
  • 2020-11-27 05:05

    A different method - using setTag() and getTag() methods of the View class.

    1. use setTag() in the onBindViewHolder method of your adapter

      @Override
      public void onBindViewHolder(myViewHolder viewHolder, int position) {
          viewHolder.mCardView.setTag(position);
      }
      

      where mCardView is defined in the myViewHolder class

      private class myViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
                 public View mCardView;
      
                 public myViewHolder(View view) {
                     super(view);
                     mCardView = (CardView) view.findViewById(R.id.card_view);
      
                     mCardView.setOnClickListener(this);
                 }
             }
      
    2. use getTag() in your OnClickListener implementation

      @Override
      public void onClick(View view) {
          int position = (int) view.getTag();           
      
      //display toast with position of cardview in recyclerview list upon click
      Toast.makeText(view.getContext(),Integer.toString(position),Toast.LENGTH_SHORT).show();
      }
      

    see https://stackoverflow.com/a/33027953/4658957 for more details

    0 讨论(0)
  • 2020-11-27 05:05
    @Override
    public void onClick(View v) {
         int pos = getAdapterPosition();
    }
    

    Simple as that, on ViewHolder

    0 讨论(0)
提交回复
热议问题