有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。


当前回答

这就是重用View的方法。OnClickListener:

public class TestAdapter extends RecyclerView.Adapter<TestAdapter.MyviewHolder>
    implements View.OnClickListener

在ViewHoder中获取项目布局的父视图:

public class MyviewHolder extends RecyclerView.ViewHolder {

    LinearLayout linearLayout;

    public MyviewHolder(View itemView) {
        super(itemView);
        linearLayout = itemView.findViewById(R.id.linear_layout_item);
    }
}

在onBindViewHolder中设置标签为位置:

@Override
public void onBindViewHolder(MyviewHolder holder, int position) {
    holder.linearLayout.setTag(position);
    holder.linearLayout.setOnClickListener(this);
}

在你的onClick实现中:

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

    switch (v.getId()) {
        case R.id.linear_layout_item:
            // do some thing with position 
            break;
    }
}

其他回答

将类标记为抽象并实现OnClick方法

public abstract class MainGridAdapter extends
    RecyclerView.Adapter<MainGridAdapter.ViewHolder> {
private List<MainListItem> mDataset;

// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ViewHolder extends RecyclerView.ViewHolder {
    // each data item is just a string in this case
    public TextView txtHeader;
    public TextView txtFooter;

    public ViewHolder(View v) {
        super(v);
        txtHeader = (TextView) v.findViewById(R.id.firstLine);
        txtFooter = (TextView) v.findViewById(R.id.secondLine);
    }
}

public void add(int position, MainListItem item) {
    mDataset.add(position, item);
    notifyItemInserted(position);
}

public void remove(MainListItem item) {
    int position = mDataset.indexOf(item);
    mDataset.remove(position);
    notifyItemRemoved(position);
}

// Provide a suitable constructor (depends on the kind of dataset)
public MainGridAdapter(List<MainListItem> myDataset) {
    mDataset = myDataset;
}

// Create new views (invoked by the layout manager)
@Override
public MainGridAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
        int viewType) {
    // create a new view
    View v = LayoutInflater.from(parent.getContext()).inflate(
            R.layout.list_item_grid_line, parent, false);
    // set the view's size, margins, paddings and layout parameters
    ViewHolder vh = new ViewHolder(v);
    return vh;
}

// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
    // - get element from your dataset at this position
    // - replace the contents of the view with that element     
    OnClickListener clickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            onItemClicked(position);
        }
    };
    holder.itemView.setOnClickListener(clickListener);
    holder.txtHeader.setOnClickListener(clickListener);
    holder.txtFooter.setOnClickListener(clickListener);
    final MainListItem item = mDataset.get(position);
    holder.txtHeader.setText(item.getTitle());
    if (TextUtils.isEmpty(item.getDescription())) {
        holder.txtFooter.setVisibility(View.GONE);
    } else {
        holder.txtFooter.setVisibility(View.VISIBLE);
        holder.txtFooter.setText(item.getDescription());
    }
}

// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
    return mDataset.size();
}

public abstract void onItemClicked(int position);

}

在绑定事件中实现单击处理程序,使其只有一个事件实现

执行此:

mAdapter = new MainGridAdapter(listItems) {         
    @Override
    public void onItemClicked(int position) {
        showToast("Item Clicked: " + position, ToastPlus.STYLE_INFO);
    }
};

同样可以做长时间点击

我知道有很多答案,但我想我也可以提供我的实现。(完整的细节可以在我回答的另一个问题中找到)。

所以,要添加一个点击监听器,你的内部ViewHolder类需要实现View.OnClickListener。这是因为你将设置一个OnClickListener到ViewHolder的构造函数的itemView参数。让我来告诉你我的意思:

public class ExampleClickViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    TextView text1, text2;

    ExampleClickViewHolder(View itemView) {
        super(itemView);

        // we do this because we want to check when an item has been clicked:
        itemView.setOnClickListener(this);

        // now, like before, we assign our View variables
        title = (TextView) itemView.findViewById(R.id.text1);
        subtitle = (TextView) itemView.findViewById(R.id.text2);
    }

    @Override
    public void onClick(View v) {
        // The user may not set a click listener for list items, in which case our listener
        // will be null, so we need to check for this
        if (mOnEntryClickListener != null) {
            mOnEntryClickListener.onEntryClick(v, getLayoutPosition());
        }
    }
}

唯一需要添加的其他东西是适配器的自定义接口和setter方法:

private OnEntryClickListener mOnEntryClickListener;

public interface OnEntryClickListener {
    void onEntryClick(View view, int position);
}

public void setOnEntryClickListener(OnEntryClickListener onEntryClickListener) {
    mOnEntryClickListener = onEntryClickListener;
}

这样,新的支持单击的适配器就完成了。

现在,让我们用它…

    ExampleClickAdapter clickAdapter = new ExampleClickAdapter(yourObjects);
    clickAdapter.setOnEntryClickListener(new ExampleClickAdapter.OnEntryClickListener() {
        @Override
        public void onEntryClick(View view, int position) {
            // stuff that will happen when a list item is clicked
        }
    });

这基本上就是设置普通适配器的方法,除了使用您创建的setter方法来控制当用户单击特定列表项时要做什么。

你也可以看看我在GitHub上做的一组关于Gist的例子:

https://gist.github.com/FarbodSalamat-Zadeh/7646564f48ee708c1582c013e1de4f07

我是这样做的,没有不必要的类、检测器等。适配器中的简单代码。特别是针对longClick的更好解决方案。

public class PasswordAdapter extends RecyclerView.Adapter<PasswordAdapter.ViewHolder> {
    private final ClickListener clickListener;

    public PasswordAdapter(ClickListener clickListener) {
         this.clickListener = clickListener;
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
        TextView name;

        public ViewHolder(View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);
            itemView.setOnLongClickListener(this);
            name = (TextView) itemView.findViewById(R.id.card_name);
        }

        @Override
        public void onClick(View v) {
            int position = getBindingAdapterPosition();
            if (position >= 0) {
                clickListener.onItemClick(position, v);
            }
        }

        @Override
        public boolean onLongClick(View v) {
            int position = getBindingAdapterPosition();
            if (position >= 0) { 
                clickListener.onItemLongClick(position, v);
                return true;
            }
            return false;
        }
    }

    public interface ClickListener {
        void onItemClick(int position, View v);
        void onItemLongClick(int position, View v);
    }
}

然后在片段或活动中,点击:

PasswordAdapter mAdapter = new PasswordAdapter(
    new PasswordAdapter.ClickListener() {
        @Override
        public void onItemClick(int position, View v) {
            Log.d(TAG, "onItemClick position: " + position);
        }

        @Override
        public void onItemLongClick(int position, View v) {
            Log.d(TAG, "onItemLongClick pos = " + position);
        }
    }
);

这就是我最后需要的东西,以防有人发现它有用:

public static class ViewHolder extends RecyclerView.ViewHolder {

    public ViewHolder(View item) {

        super(item);
        item.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("RecyclerView", "onClick:" + getAdapterPosition());
            }
        });

    }
}

来源:http://blog.csdn.net/jwzhangjie/article/details/36868515

查看类似的问题@CommonsWare的评论链接到this,它在viewHolder中实现了OnClickListener接口。

下面是ViewHolder的一个简单例子:

/** Declare global with in adapter class. */
TextView textView;

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

    private ViewHolder(View itemView) {
        super(itemView);
        itemView.setOnClickListener(this);
        textView = (TextView) view.findViewById(android.R.id.text1);   
    }

    @Override
    public void onClick(View view) {
        Toast.makeText(view.getContext(), "position = " + getLayoutPosition(), Toast.LENGTH_SHORT).show();
         
        /** Go through each item if you have few items within RecyclerView. */
        if (getLayoutPosition() == 0) {
           // Do whatever you want here
        } else if(getLayoutPosition() == 1) { 
           // Do whatever you want here
        } else if(getLayoutPosition() == 2) {
           // Do whatever you want here
        }

        /** Or you can use For loop if you have long list of items. */
        for (int i = 0; i < exampleList.size(); i++) {
            // Do whatever you want here
        }
    }
}

在你的RecyclerView中创建ViewHolder。适配器看起来像这样:

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext())
    View view = inflater.inflate(android.R.layout.simple_list_item_1, parent, false);
    return new ViewHolder(view);
}