简体   繁体   中英

Get Position data from Item in RecyclerView

I recently migrated from ListView to RecyclerView... Everything seems fine except for that I don't know how to get the Data from an RecyclerView Item... In ListView Item OnClick, I previously used getItemAtPosition but it isn't there in RecyclerView...

here is the relevant part of the Code... - MainActivity.java

private SDKP mSelectedPackage;
RecyclerView mRecyclerView;

mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
            //I'm STUCK HERE!
             mSelectedPackage = (SDKPackage) mRecyclerView.getItemAtPosition(position);
                    openContextMenu(view);

  /*Toast.makeText(MainActivity.this, "Card at " + position + " is clicked", Toast.LENGTH_SHORT).show();*/
            }
        }));


@Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo)
    {
        mSelectedPackage.inflateMenu(menu);
        super.onCreateContextMenu(menu, v, menuInfo);
    } 

    @Override
    public boolean onContextItemSelected(MenuItem item)
    {
        return mSelectedPackage.onMenuClick(this, item);
    }

here's the inflateMenu(ContextMenu menu) method -

public void inflateMenu(ContextMenu menu)
    {
        menu.setHeaderTitle(getPackageName());
        if (isDownloading())
        {
            menu.add(Menu.NONE, 256, Menu.NONE, "Cancel download");
        }
        else if (isInstalled())
        {
            menu.add(Menu.NONE, 257, Menu.NONE, "Uninstall");
        }
        else
        {
            int i = 0;
            for (SDKA archive : archives)
            {
                menu.add(Menu.NONE, i++, Menu.NONE, archive.getArchiveName());
            }
        }
    }

    public boolean onMenuClick(Activity parent, MenuItem item)
    {
        if (item.getItemId() >= 256)
            uninstall();
        else
        {
            SDKA archive = archives.get(item.getItemId());
            if (archive != null)
            {
                archive.onClick(parent);
            }
        }
        return true;
    }

When I used ListView I used -

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
            {
                @Override
                public void onItemClick(AdapterView<?> adapter, View view, int position, long arg)
                {
                    mSelectedPackage = (SDKP) mPackageList.getItemAtPosition(position);
                    openContextMenu(view);
                }
            });

There is no equivalent for getItemAtPosition() in recyclerview. To get around this you can create an interface on your adapter and implement that interface on your ViewHolder , which will listen for your onClick() .

 public interface OnItemClickListener {
        public void onItemClick(View view, int position);
  }

Then have your ViewHolder implement the interface.

public static class MyViewHolder extends RecyclerView.MyViewHolder implements View.OnClickListener {

private OnItemClickListener mListener;

public MyViewHolder(View itemView) {
    super(itemView);
    itemView.setOnClickListener(this);

}

 public MyViewHolder(View itemView, OnItemClickListener listener) {
    this(itemView);
    mListener = listener;
}


@Override
public void onClick(View v) {
    if (mListener != null) {
        mListener.onItemClick(v, getPosition());
    }
}

-Alternatively you can use rxjava.

你应该设置View.OnClickListeneritemViewRecyclerView.ViewHolder类。

You can achieve this by multiple ways

1 ) item click listener by implementing the RecyclerView.OnItemTouchListener

 import android.content.Context; import android.support.v7.widget.RecyclerView; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener { private OnItemClickListener mListener; public interface OnItemClickListener { public void onItemClick(View view, int position); } GestureDetector mGestureDetector; public RecyclerItemClickListener(Context context, OnItemClickListener listener) { mListener = listener; mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { return true; } }); } @Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) { View childView = view.findChildViewUnder(e.getX(), e.getY()); if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) { mListener.onItemClick(childView, view.getChildAdapterPosition(childView)); } return false; } @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { } }

Now using this custom class

 recyclerView.addOnItemTouchListener( new RecyclerItemClickListener(context, new RecyclerItemClickListener.OnItemClickListener() { @Override public void onItemClick(View view, int position) { // TODO Handle item click } }) );

2) Getting item at position using interface in adapter

 public class NewRecyclerView extends RecyclerView.Adapter<NewRecyclerView.ViewHolder> { private List<MyItem> myItems; private ItemListener myListener; public NewRecyclerView(List<MyItem> items, ItemListener listener) { myItems = items; myListener = listener; } public void setListener(ItemListener listener) { myListener = listener; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new ViewHolder(LayoutInflater.from(parent.getContext()) .inflate(R.layout.LAYOUT, parent, false)); // TODO } @Override public int getItemCount() { return myItems.size(); } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.setData(myItems.get(position)); } public interface ItemListener { void onItemClick(MyItem item); } public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { // TODO - Your view members public MyItem item; public ViewHolder(View itemView) { super(itemView); itemView.setOnClickListener(this); // TODO instantiate/assign view members } public void setData(MyItem item) { this.item = item; // TODO set data to view } @Override public void onClick(View v) { if (myListener != null) { myListener.onItemClick(item); } } }

In your activty or fragment implement NewRecyclerView.ItemListener will give item at click position

with @Bob's suggestion, I did it this way without much code... :)

In my Adapter, I implemented a custom method like -

public Object getMyPos(int pos){
         return packages.get(pos);
   }

& then in the RecyclerItem OnClick, I used it like -

mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
            mSelectedPackage = (SDKP) ((ShAdapter)mRecyclerView.getAdapter()).getMyPos(position);

                    openContextMenu(view);
            }
        }));

To get Position data from Item in RecyclerView

public class ViewHolder extends RecyclerView.ViewHolder {
  

    public ViewHolder(View itemView) {
        super(itemView);


    
        // on item click
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // get position
                int position = getAdapterPosition();

                // check if item still exists
                if (position != 0 || position!=RecyclerView.NO_POSITION){

                    // means if position is not equal to 0 and item exist
                    // then it should display a toast with the category name
                    // to the user when the category item or data is clicked

                    // get position of each item on recyclerView

        

                    CategoriesList clickedItem = categoriesLists.get(position);
                   Toast.makeText(v.getContext(), "You clicked " +clickedItem.getCatName(), Toast.LENGTH_SHORT).show();

    /* CategoryList is the model class i created so change it 
          with your model class
           */



// if you want to send the user to an activity when the item is clicked then 
// this is how to go about it 




                    if (position == 1){
                        v.getContext().startActivity(new Intent(v.getContext(), LoginActivity.class));
                    }
                    else{
                        if (position == 2){
                            v.getContext().startActivity(new Intent(v.getContext(), SignUpActivity.class));
                        }
                    }
                }
            }
        });
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM