如何在recyclerView中获取cardView项目的位置?

5

我为RecyclerView创建了一个适配器类,用于填充卡片视图布局。它工作正常,但是当我点击RecyclerView中的CardView项目时,我需要获取该CardView项的位置,并基于此编写Intent活动。同时,我需要知道如何在向右滑动时删除该CardView项。

MyAdapter 类。
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private NavigationItem[] navigationItem;
    private Context mContext;

    public MyAdapter(NavigationItem[] navigationItem) {
        this.navigationItem = navigationItem;
    }

    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemLayoutView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.navigation_row_cardview, null);
        ViewHolder viewHolder = new ViewHolder(itemLayoutView);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(MyAdapter.ViewHolder holder, int position) {
        holder.txtViewTitle.setText(navigationItem[position].getTitle());
    }

    @Override
    public int getItemCount() {
        return navigationItem.length;
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        @InjectView(R.id.hambergerRecyclerView)
        public RelativeLayout recyclerView;
        public TextView txtViewTitle;

        public ViewHolder(final View itemLayoutView) {
            super(itemLayoutView);
            ButterKnife.inject(this, itemLayoutView);
            txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.navigationItemOptionName);

            itemLayoutView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // int itemPosition = RecyclerView.getChildPosition(view);
                    int itemPosition = recyclerView.getChildAdapterPosition(view);
                    String item = navigationItem.get(itemPosition);
                    Toast.makeText(mContext, item, Toast.LENGTH_LONG).show();
                }
            });
        }
    }
}
5个回答

15

简短回答

  1. 获取CardView项的位置

    当我在RecyclerView中点击CardView时,我需要获取该CardView项的位置。

    在您的适配器的onBindViewHolder方法中使用setTag(),并在OnClickListener实现中使用getTag()。

    您还可以使用getAdapterPosition() - 参见https://dev59.com/pl4c5IYBdhLWcg3weaP8#27886776

    编辑:如评论中所述,如果需要实现滑动,请改用getAdapterPosition()方法 - 这样可以确保位置不会偏移。

  2. 启动Activity

    基于此,我需要编写Intent活动

    在您的OnClickListener实现中创建并启动一个新的Intent。

    Intent newIntent = new Intent(this, YourNewActivity.class);    
    startActivity(newIntent);
    

长回答

如何获取RecyclerView列表中CardView项的位置?

当我点击RecyclerView中的CardView项时,我需要获取该CardView项的位置。

我使用了View的setTag()getTag()方法。您还可以使用getAdapterPosition - 请参见https://dev59.com/pl4c5IYBdhLWcg3weaP8#27886776

View可以是TextView、ImageView、CardView,甚至是View(其中可能包含文本视图、图像视图等) - 基本上如果它继承自View对象,则可以使用。

  • 首先,请查看下面的onCreateViewHolder方法。 layoutInflater会膨胀我的XML布局文件item_view.xml中的视图。该布局文件中的任何视图都将在构造函数中可访问。

  • @Override
    public myViewHolder onCreateViewHolder(ViewGroup parentViewGroup, int i) {
        ...
    
        View itemView = layoutInflater.inflate(R.layout.item_view, parentViewGroup, false);
        return new myViewHolder(itemView);
    }
    
    定义一个常量来表示您的View对象,例如mView,并将其设置为您希望设置OnClickListener或从中获取位置的View。
    private class myViewHolder extends RecyclerView.ViewHolder {
        public View mView;
    
        public myViewHolder(View view) {
            super(view);
            mView = view;
        }
    }
    

    在之前的情况下,我将mView设置为父视图。

    如果你想从onCreateViewHolder中填充的item_view.xml布局文件中访问特定的视图--定义另一个常量,使用view.findViewbyId()设置它,并不要忘记强制转换视图(见下文)。

    private class myViewHolder extends RecyclerView.ViewHolder {
        public CardView mCardView;
    
        public myViewHolder(View view) {
            super(view);
            mCardView = (CardView) view.findViewById(R.id.card_view);
        }
    }
    
  • 在您的适配器类的onBindViewHolder方法中使用setTag()。现在,每个CardView都将其在RecyclerView列表中的位置作为标签。

  • @Override
    public void onBindViewHolder(myViewHolder viewHolder, int position) {
        viewHolder.mCardView.setTag(position);
    }
    
  • 使用 getTag() 方法访问 RecyclerView 列表中每个 CardView 的位置:我们有两种方法可以实现此功能(在 Activity 中或在 XML 中)。

    在 ViewHolder 构造函数中设置 onClickListener(不要忘记实现 View.OnClickListener),并编辑 onClick 方法。

  • 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);
               }
           }
    
    @Override
    public void onClick(View view) {
        int position = (int) view.getTag();           
        Toast.makeText(view.getContext(),Integer.toString(position),Toast.LENGTH_SHORT).show();
    }
    

    或者在您的CardView XML布局中设置onClick属性android:onClick="positionAction"

    <android.support.v7.widget.CardView
        android:id="@+id/card_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="positionAction">    
    
    </android.support.v7.widget.CardView>
    

    并在活动中创建一个包含可循环视图的方法。

    public void positionAction(View view) {
        int position = (int) view.getTag();
        Toast.makeText(view.getContext(),Integer.toString(position),Toast.LENGTH_SHORT).show();
    }
    

对于上面的两个选项,如果你想获得一个字符串位置,你可以使用String position = "Position " + view.getTag.toString();代替int position = (int) view.getTag;

注意1:你只能在已调用setTag()方法的View对象上使用getTag()方法(否则会出现NullPointerException异常)。

注意2:我没有为setTag()和getTag()方法使用关键字,如果你为每个View设置多个标签,那么你可以这样做。

如何根据点击的CardView启动一个新的Activity?

基于此,我需要编写一个Intent活动。

要根据用户单击的CardView项目启动新的Activity,请在onClick方法或positionAction方法中添加以下两行代码(根据您选择使用的方法而定)。

Intent newIntent = new Intent(this, YourNewActivity.class);    
startActivity(newIntent);

如果您想将一个对象从一个活动传递到另一个活动,请使用

Intent newIntent = new Intent(this, YourNewActivity.class);
newIntent.putExtra("Item Object", itemList.get(position));
startActivity(newIntent);

并且在新的活动中(YourNewActivity类):

itemReceived = new Item();
itemReceived = (Item) getIntent().getSerializableExtra("Item Object");

其中,itemList是一个Item()对象的ArrayList。

参考文献:StackOverflow | Tuts+


1
在RecyclerView上使用setTag()和getTag()与滑动操作不兼容。一旦您删除一个项目,所有由setTag()记录的位置都将对删除位置下方的所有项目失效。 - theczechsensation
@theczechsensation 你是对的 - 我已经编辑了我的回答。谢谢! - bastien

2
onBindViewHolder 中实现 onClick,然后你就可以得到位置。

@Madhu 你不需要使用getAdapterPosition(),你可以使用onBindViewHolder(ViewHolder holder, int position)的position。 - Norutan

2

请按照以下方式更新您的ViewHolder:

public class ViewHolder extends RecyclerView.ViewHolder { 
    @InjectView(R.id.hambergerRecyclerView)
    public RelativeLayout recyclerView;
    public TextView txtViewTitle;
    public ViewHolder(final View itemLayoutView) {
        super(itemLayoutView);
        ButterKnife.inject(this, itemLayoutView);
        txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.navigationItemOptionName);

        itemLayoutView.setOnClickListener(new View.OnClickListener() {
            @Override 
            public void onClick(View view) {
               //int itemPosition = RecyclerView.getChildPosition(view); 
                int itemPosition=getAdapterPosition();
                String item = navigationItem.get(itemPosition);
                Toast.makeText(mContext, item, Toast.LENGTH_LONG).show();
            } 
        }); 
    } 


} 

字符串 item = navigationItem.get(itemPosition); ==> 这里 get()显示错误...你能检查一下吗... - user4715375
navigationItem.get(getAdapterPosition()); 改成这样 - Madhu
@androidstar 仍然没有得到位置吗? - rKrishna

1
你可以尝试从onBindViewHolder将位置传递给ViewHolder
@Override   
public void onBindViewHolder(MyAdapter.ViewHolder holder, int position) {
    holder.txtViewTitle.setText(navigationItem[position].getTitle());
    //set position to holder
    holder.position = position; 
}


public class ViewHolder extends RecyclerView.ViewHolder {
        @InjectView(R.id.hambergerRecyclerView)
        public RelativeLayout recyclerView;
        public TextView txtViewTitle;
        //have a position field in view holder
        public int position;

        public ViewHolder(final View itemLayoutView) {
            super(itemLayoutView);
            ButterKnife.inject(this, itemLayoutView);
            txtViewTitle = (TextView) itemLayoutView.findViewById(R.id.navigationItemOptionName);

            itemLayoutView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // int itemPosition = RecyclerView.getChildPosition(view);
                    int itemPosition = position;
                    String item = navigationItem.get(itemPosition);
                    Toast.makeText(mContext, item, Toast.LENGTH_LONG).show();
                }
            });
        }
}

0

在你的适配器的onBindViewHolder中尝试这个

myViewHolder1.itemView.setTag(new Integer(position));

然后在您的OnClickListener中获取如下:

Integer pos;
pos = (Integer) view.getTag();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接