如何在RecyclerView中获取所选位置?

Huk*_*ABA 53 android android-support-library android-cardview android-recyclerview

我正在试验支持库的recyclerview和卡片.我有回收卡的卡片.每张卡片的右上角都有一个"x"图标可将其删除:

该卡的xml, list_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="5dp">
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/taskDesc"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:textSize="40sp"
        android:text="hi"/>
    <ImageView
        android:id="@+id/xImg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:src="@drawable/ic_remove"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
Run Code Online (Sandbox Code Playgroud)

我试图用我会在使用的位置标记的行notifyItemRemoved(position)TaskAdapter.java:

public class TaskAdapter extends RecyclerView.Adapter<TaskAdapter.TaskViewHolder>  {

private List<Task> taskList;
private TaskAdapter thisAdapter = this;


// cache of views to reduce number of findViewById calls
public static class TaskViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    protected TextView taskTV;
    protected ImageView closeBtn;
    public TaskViewHolder(View v) {
        super(v);
        taskTV = (TextView)v.findViewById(R.id.taskDesc);
    }

    @Override
    public void onClick(View v) {
        int position = v.getTag();
        adapter.notifyItemRemoved(position);
    }
}


public TaskAdapter(List<Task> tasks) {
    if(tasks == null)
        throw new IllegalArgumentException("tasks cannot be null");
    taskList = tasks;
}


// onBindViewHolder binds a model to a viewholder
@Override
public void onBindViewHolder(TaskViewHolder taskViewHolder, int pos) {
    final int position = pos;
    Task currTask = taskList.get(pos);
    taskViewHolder.taskTV.setText(currTask.getDescription());

    taskViewHolder.closeBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            thisAdapter.notifyItemRemoved(position);
        }
    });
}

@Override
public int getItemCount() {
    return taskList.size();
}


// inflates row to create a viewHolder
@Override
public TaskViewHolder onCreateViewHolder(ViewGroup parent, int pos) {
    View itemView = LayoutInflater.from(parent.getContext()).
                                   inflate(R.layout.list_item, parent, false);

    return new TaskViewHolder(itemView);
}
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为您无法设置标签,也无法从中访问适配器 onClick.

tyc*_*czj 102

设置你onClickListeneronBindViewHolder(),你可以从那里访问位置.如果你在它们中设置它们,ViewHolder你将无法知道点击了什么位置,除非你也将位置传递给了ViewHolder

编辑

正如所pskink指出ViewHoldergetPosition()那样,你最初做的方式是正确的.

单击视图后,您可以getPosition()在您的视图中使用ViewHolder它返回位置

更新

getPosition() 现已弃用并替换为 getAdapterPosition()

  • @tyczj ViewHolder.getPosition(),顺便说一句,当你创建一个ViewHolder你不知道位置,位置在onBindViewHolder中设置 (9认同)
  • 你能展示一些代码吗?如果taskViewHolder没有setOnClickListener方法,我怎么能这样做? (3认同)
  • @tyczj没有,更好的地方是在ViewHolder ctor中设置监听器,ViewHolders知道自己的位置 (3认同)

bas*_*ien 14

一种不同的方法 - 使用View类的setTag()getTag()方法.

  1. 在适配器的onBindViewHolder方法中使用setTag()

    @Override
    public void onBindViewHolder(myViewHolder viewHolder, int position) {
        viewHolder.mCardView.setTag(position);
    }
    
    Run Code Online (Sandbox Code Playgroud)

    其中mCardView在myViewHolder类中定义

    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);
               }
           }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在OnClickListener实现中使用getTag()

    @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();
    }
    
    Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅/sf/answers/2311956741/


Mik*_*eps 8

补充@tyczj答案:

通用适配器Pseido代码:

public abstract class GenericRecycleAdapter<T, K extends RecyclerView.ViewHolder> extends RecyclerView.Adapter{ 

private List<T> mList;
//default implementation code 

public abstract int getLayout();

@Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(getLayout(), parent, false);
        return getCustomHolder(v);
    }

    public Holders.TextImageHolder getCustomHolder(View v) {
        return new Holders.TextImageHolder(v){
            @Override
            public void onClick(View v) {
                onItem(mList.get(this.getAdapterPosition()));
            }
        };
    }

abstract void onItem(T t);

 @Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    onSet(mList.get(position), (K) holder);

}

public abstract void onSet(T item, K holder);

}
Run Code Online (Sandbox Code Playgroud)

ViewHolder:

public class Holders  {

    public static class TextImageHolder extends RecyclerView.ViewHolder implements View.OnClickListener{

        public TextView text;

        public TextImageHolder(View itemView) {
            super(itemView);
            text = (TextView) itemView.findViewById(R.id.text);
            text.setOnClickListener(this);


        }

        @Override
        public void onClick(View v) {

        }
    }


}
Run Code Online (Sandbox Code Playgroud)

适配器用法:

public class CategoriesAdapter extends GenericRecycleAdapter<Category, Holders.TextImageHolder> {


    public CategoriesAdapter(List<Category> list, Context context) {
        super(list, context);
    }

    @Override
    void onItem(Category category) {

    }


    @Override
    public int getLayout() {
        return R.layout.categories_row;
    }

    @Override
    public void onSet(Category item, Holders.TextImageHolder holder) {

    }



}
Run Code Online (Sandbox Code Playgroud)


not*_*one 5

 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());
    }
}
Run Code Online (Sandbox Code Playgroud)