在Activity中定义RecyclerView onCLickListener

时间:2016-03-13 12:42:20

标签: android android-recyclerview

RecyclerView与ListView不同,因为它没有提供onItemCLickListener类来处理点击事件。

如果通过在ViewHolder中定义onClickListener,点击项目后幕后不会发生很多事情,可以解决这个问题。

如果文本或任何必须传递给下一个Activity的内容在ViewHolder有权访问的视图中确实存在,但是它是具有RecyclerView的Activity的一部分会怎么样?

在这种情况下,必须在活动内部实现onClickListener,以便可以转发文本。这是可能的。

  1. 一种方法是添加一个隐藏该文本的Invisible View,然后执行之前已完成的操作;在适配器中实现onClickListener。

  2. 以某种方式将该文本传递给适配器。

  3. 怎么能" 2。"实施?

6 个答案:

答案 0 :(得分:21)

请参阅以下示例,以创建RecyclerView OnClick

示例代码:

public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ViewHolder> {

public interface OnItemClickListener {
    void onItemClick(ContentItem item);
}

private final List<ContentItem> items;
private final OnItemClickListener listener;

public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
    this.items = items;
    this.listener = listener;
}

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

@Override public void onBindViewHolder(ViewHolder holder, int position) {
    holder.bind(items.get(position), listener);
}

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

static class ViewHolder extends RecyclerView.ViewHolder {

    private TextView name;
    private ImageView image;

    public ViewHolder(View itemView) {
        super(itemView);
        name = (TextView) itemView.findViewById(R.id.name);
        image = (ImageView) itemView.findViewById(R.id.image);
    }

    public void bind(final ContentItem item, final OnItemClickListener listener) {
        name.setText(item.name);
        Picasso.with(itemView.getContext()).load(item.imageUrl).into(image);
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override public void onClick(View v) {
                listener.onItemClick(item);
            }
        });
    }
}
}

使用以下代码使用RecyclerView适配器:

recycler.setAdapter(new ContentAdapter(items, new ContentAdapter.OnItemClickListener() {
@Override public void onItemClick(ContentItem item) {
    Toast.makeText(getContext(), "Item Clicked", Toast.LENGTH_LONG).show();
}
}));

请参阅Set a click listener to a RecyclerView

希望它对你有所帮助。

答案 1 :(得分:13)

在您的活动中写一个公共函数,如:

public void onClickCalled(String anyValue) {
    // Call another acitivty here and pass some arguments to it.
}

现在在适配器的onClick功能

@Override
public void onClick(View view) {
    ((YouActivityClass) context).onClickCalled("your argument here");
}

答案 2 :(得分:1)

这可以通过创建自己的侦听器并将其传递给适配器来解决。

public interface PositionClickListener
{
    void itemClicked(int position);
}

Activity可以实现此接口,或实例化匿名内部类。所以你的适配器看起来像这样:

public class MyRecyclerAdapter extends RecyclerView.Adapter
{
    public final PositionClickListener listener;

    public MyRecyclerAdapter(PositionClickListener listener)
    {
         this.listener = listener;
    }

    private void createView(int position)
    {
        View v = new View();
        v.setOnClickListener(new OnClickListener(){
            listener.itemClicked(position);
        });
    }
}

答案 3 :(得分:1)

ListView有一个onItemClickListener,RecyclerView有addOnItemTouchListener

您可以从活动中向回收者视图提供监听器,因此范围将使监听器能够引用该文本。

您可以使用类似OnItemTouchListener的实现,它也可以捕获左右滑动。

public class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {

    private static final String TAG = "RecyclerTouchListener";

    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    private static final int SWIPE_MAX_OFF_PATH = 250;

    private OnTouchActionListener mOnTouchActionListener;
    private GestureDetectorCompat mGestureDetector;

    public static interface OnTouchActionListener {
        public void onLeftSwipe(View view, int position);
        public void onRightSwipe(View view, int position);
        public void onClick(View view, int position);
    }

    public RecyclerTouchListener(Context context, final RecyclerView recyclerView,
                             OnTouchActionListener onTouchActionListener){

        mOnTouchActionListener = onTouchActionListener;
        mGestureDetector = new GestureDetectorCompat(context,new GestureDetector.SimpleOnGestureListener(){

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            Log.d(TAG, "On Single Tap Confirmed");
            // Find the item view that was swiped based on the coordinates
            View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
            int childPosition = recyclerView.getChildPosition(child);
            mOnTouchActionListener.onClick(child, childPosition);
            return false;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2,
                               float velocityX, float velocityY) {
            Log.d(TAG, "onFling: " + e1.toString() + e2.toString());

            try {
                if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) {
                    return false;
                }

                // Find the item view that was swiped based on the coordinates
                View child = recyclerView.findChildViewUnder(e1.getX(), e1.getY());
                int childPosition = recyclerView.getChildPosition(child);

                // right to left swipe
                if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {

                    Log.d(TAG, "Left Swipe");
                    if (mOnTouchActionListener != null && child != null) {
                        mOnTouchActionListener.onLeftSwipe(child, childPosition);
                    }

                } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                    Log.d(TAG, "Right Swipe");
                    if (mOnTouchActionListener != null && child != null) {
                        mOnTouchActionListener.onRightSwipe(child, childPosition);
                    }
                }
            } catch (Exception e) {
                // nothing
            }

            return false;
        }
    });
}

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        mGestureDetector.onTouchEvent(e);
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        // do nothing
    }

}

然后在您的活动中添加您的听众

 mRecyclerView.addOnItemTouchListener(
        new RecyclerTouchListener(getActivity(), mRecyclerView,
            new RecyclerTouchListener.OnTouchActionListener() {
                @Override
                public void onClick(View view, int position) {
                }
                @Override
                public void onRightSwipe(View view, int position) {
                }
                @Override
                public void onLeftSwipe(View view, int position) {
                }
            }))

答案 4 :(得分:0)

它很容易,我们没有创建接口看看我的代码只是把这个小代码我们

@Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
      holder.img.setImageDrawable(img[position%img.length]);
        holder.bodyPartName.setText(bodyPart[position]);
        if(position==0) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Context c = v.getContext();
                    Intent intent = new Intent(c, BodyPartExcercise.class);
                    c.startActivity(intent);
                }
            });
        }
    }

答案 5 :(得分:0)

我遇到了第一个好的答案这个问题。 出现问题(上下文错误)。

我将以下代码放在onBindViewHolder中。

在适配器中:

        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ((YouActivityClass) v.getContext()).onClickCalled("your argument here");
            }
        });

活动中:

    public void onClickCalled(String anyValue) {
        // Call another acitivty here and pass some arguments to it.

    }

整体