【问题标题】:Get Position data from Item in RecyclerView从 RecyclerView 中的 Item 获取位置数据
【发布时间】:2017-08-06 17:27:20
【问题描述】:

我最近从 ListView 迁移到 RecyclerView... 一切似乎都很好,除了我不知道如何从 RecyclerView 项目中获取数据...... 在 ListView Item 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 menu) 方法 -

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

【问题讨论】:

  • 使用getAdapterPosition()

标签: android listview android-recyclerview


【解决方案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。

【讨论】:

    【解决方案2】:

    您应该在RecyclerView.ViewHolder 类中将View.OnClickListener 设置为itemView

    【讨论】:

    • 那我怎样才能在那个 OnClickListener 中获得像 getItemAtPosition(int) 这样的方法呢? :)
    • 您可以从ViewHolder 调用getAdapterPosition(),它会为您提供适配器位置。使用该位置,您可以从支持数据中获取项目 - 它可能来自 ListCursor 行,具体取决于您的实施。
    • 如果在List中怎么办?
    • getAdapterPosition() 给你一个position。现在您可以像这样从 List 中获取项目:list.get(position)
    【解决方案3】:

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

    1 ) 通过实现 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) {
        }
    }

    现在使用这个自定义类

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

    2) 使用适配器中的接口获取项目位置

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

    在您的活动或片段中实现 NewRecyclerView.ItemListener 将在点击位置提供项目

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        从 RecyclerView 中的 Item 中获取 Position 数据

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

        【讨论】:

        • 如果您发现任何问题,请通过 mensahokobright@gmail.com 联系我
        猜你喜欢
        • 1970-01-01
        • 2020-09-18
        • 1970-01-01
        • 2020-12-09
        • 1970-01-01
        • 2015-11-17
        • 1970-01-01
        • 2015-08-10
        • 1970-01-01
        相关资源
        最近更新 更多