从RecyclerView中的Item获取位置数据

时间:2017-08-06 17:27:20

标签: android listview android-recyclerview

我最近从ListView迁移到RecyclerView ... 一切似乎都很好,除了我不知道如何从RecyclerView项目获取数据... 在ListView项目OnClick中,我之前使用过getItemAtPosition但它在RecyclerView中不存在...

这是守则的相关部分...... - 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);
    }

这是inflateMenu(ContextMenu菜单)方法 -

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

当我使用ListView时,我使用了 -

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

5 个答案:

答案 0 :(得分:1)

在recyclerview中没有getItemAtPosition()的等价物。要解决此问题,您可以在适配器上创建一个界面,并在ViewHolder上实现该界面,该界面将监听您的onClick()

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

然后让你的ViewHolder实现界面。

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

- 或者你可以使用rxjava。

答案 1 :(得分:0)

您应该将View.OnClickListener设置为itemView课程中的RecyclerView.ViewHolder

答案 2 :(得分:0)

  

您可以通过多种方式实现这一目标

     

1)项目点击监听器,实现RecyclerView.OnItemTouchListener

&#13;
&#13;
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) {
    }
}
&#13;
&#13;
&#13;

  

现在使用此自定义类

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

2)使用适配器中的接口

获取项目

&#13;
&#13;
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);
            }
        }
    }
&#13;
&#13;
&#13;

在你的activty或片段实现中,NewRecyclerView.ItemListener将在点击位置给出项目

答案 3 :(得分:0)

根据@ Bob的建议,我这样做没有太多代码......:)

在我的适配器中,我实现了一个自定义方法,如 -

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

&安培;然后在RecyclerItem OnClick中,我使用它像 -

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

答案 4 :(得分:0)

从 RecyclerView 中的 Item 获取位置数据

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