RecyclerView 点击事件监听器

6

如何实现RecyclerViewonItemClick监听器,就像我们使用ListView一样,这是我的旧适配器类使用ListView

public class GenreAdapter extends BaseAdapter {

....

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    // convert view = design
    View v = convertView;
    if (v == null) {
        holder = new ViewHolder();
        v = vi.inflate(Resource, null);
        holder.textTitle = (TextView) v.findViewById(R.id.textTitle);
        v.setTag(holder);
    } else {
        holder = (ViewHolder) v.getTag();
    }

    holder.textTitle.setText(genreArrayList.get(position).getTitle());

    v.setOnClickListener(new OnClickListener() {

       @Override
       public void onClick(View v) {                          

           Bundle bundle = new Bundle();
           bundle.putSerializable("data", genreArrayList);
           bundle.putInt("current", position);             

           Intent intent = new Intent(context, MovieActivity.class);
           intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
           intent.putExtras(bundle);
           context.startActivity(intent);

        }
    });

    return v;
}

static class ViewHolder {
    public TextView textTitle;
}

MainFragment.java:-

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.fragment_main, container, false);

        /* Initialize recycler view */
        mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

        mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));

        list = new ArrayList<MainPoho>();
        adapter = new MainAdapter(getActivity(), list);
        mRecyclerView.setAdapter(adapter);

        .......

}

这是我的新的 Adapter 类,使用了 RecyclerView

public class MyRecyclerAdapter extends RecyclerView.Adapter<FeedListRowHolder> {

    private List<FeedItem> feedItemList;
    private Context mContext;

    public MyRecyclerAdapter(Context context, List<FeedItem> feedItemList) {
        this.feedItemList = feedItemList;
        this.mContext = context;
    }

    @Override
    public FeedListRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_row, null);
        FeedListRowHolder mh = new FeedListRowHolder(v);
        return mh;
    }

    @Override
    public void onBindViewHolder(FeedListRowHolder feedListRowHolder, int i) {
        FeedItem feedItem = feedItemList.get(i);        
        feedListRowHolder.title.setText(Html.fromHtml(feedItem.getTitle()));
    }

    @Override
    public int getItemCount() {
        if(feedItemList !=null){
            return feedItemList.size();
          } else {
            return 0;
          }
    }

public class FeedListRowHolder extends RecyclerView.ViewHolder {
    protected TextView title;

    public FeedListRowHolder(View view) {
        super(view);
        this.title = (TextView) view.findViewById(R.id.title);
    }

FeedItem.java:-

public class FeedItem {
    private String title;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

}
3个回答

8

首先在您的viewHolder中存储整个视图:

  public class FeedListRowHolder extends RecyclerView.ViewHolder {
     protected TextView title;
     protected View mRootView;

    public FeedListRowHolder(View view) {
        super(view);
        this.title = (TextView) view.findViewById(R.id.title);
        mRootView = view;
    }

然后在 onBindViewHolder 中设置点击监听器:

@Override
public void onBindViewHolder(FeedListRowHolder feedListRowHolder, int i) {
    FeedItem feedItem = feedItemList.get(i);        
    feedListRowHolder.title.setText(Html.fromHtml(feedItem.getTitle()));
    feedListRowHolder.mRootView.setOnClickListener(new OnClickListener(){

        @Override
        public void onClick(View v) {

        }
   });
}

谢谢,但只有在我连续点击文本时才有效,而在ListView中,无论我们在哪一行点击都有效...那么可能是什么原因呢? - Sun
我认为如果你将点击监听器设置为根视图,你就可以得到你想要的结果。 - mmlooloo
我不确定你的问题是什么,我看到了你的其他帖子,很抱歉现在我无法创建任何样本项目进行测试,但我已经在我的一个应用程序中实现了我发布的内容。 :-( - mmlooloo
我不是在寻找任何示例项目,我的问题是为什么当我点击行时,点击无响应。 - Sun
当你扩展RecyclerView.ViewHolder时,mRootView已经可用,但被称为itemView - finstas
不要将点击监听器添加到 onBindViewHolder 方法中,这会为列表中的每个项目创建一个新的 onClickListener 对象。请将其添加到您自定义的 ViewHolder 中。 - Jeffrey

1
首先,您需要实现自己的OnItemTouchListener:
static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener{

    private GestureDetector gestureDetector;

    public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener){
        gestureDetector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener(){
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                //here get the view that has been touched
                View child = recyclerView.findChildViewUnder(e.getX(),e.getY());

                //now pass the item and its position to your click listener 
                if(child!=null && clickListener!=null){
                    clickListener.onClick(child, recyclerView.getChildPosition(child));
                }

                return true;
            }

            @Override
            public void onLongPress(MotionEvent e) {
            }
        });
    }

    public static interface ClickListener {
        public void onClick(View view, int position);
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
        //use the gesture detector to intercept singletap and longtouch events
        gestureDetector.onTouchEvent(motionEvent);
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView recyclerView, MotionEvent motionEvent) {
    }
}

然后您将需要实现ClickListener,该ClickListener将由上面的RecyclerTouchListener调用:

private RecyclerTouchListener.ClickListener mClickListener =  new RecyclerTouchListener.ClickListener() {
    @Override
    public void onClick(View view, final int position) {
            //Do something with your item...
            mRecyclerAdapter.getElementAt(position).doSomething();

        }

    }

1
我知道有点晚了,但是对于那些游荡而不迷失的人来说,我在这里找到了一个优雅的解决方案。
所以基本上你需要创建一个类似下面的ItemClickSupport类。
public class ItemClickSupport {
    private final RecyclerView mRecyclerView;
    private OnItemClickListener mOnItemClickListener;
    private OnItemLongClickListener mOnItemLongClickListener;
    private View.OnClickListener mOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mOnItemClickListener != null) {
                RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
                mOnItemClickListener.onItemClicked(mRecyclerView, holder.getAdapterPosition(), v);
            }
        }
    };
    private View.OnLongClickListener mOnLongClickListener = new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            if (mOnItemLongClickListener != null) {
                RecyclerView.ViewHolder holder = mRecyclerView.getChildViewHolder(v);
                return mOnItemLongClickListener.onItemLongClicked(mRecyclerView, holder.getAdapterPosition(), v);
            }
            return false;
        }
    };
    private RecyclerView.OnChildAttachStateChangeListener mAttachListener
        = new RecyclerView.OnChildAttachStateChangeListener() {
        @Override
        public void onChildViewAttachedToWindow(View view) {
            if (mOnItemClickListener != null) {
                view.setOnClickListener(mOnClickListener);
            }
            if (mOnItemLongClickListener != null) {
                view.setOnLongClickListener(mOnLongClickListener);
            }
        }

        @Override
        public void onChildViewDetachedFromWindow(View view) {

        }
    };

    private ItemClickSupport(RecyclerView recyclerView) {
        mRecyclerView = recyclerView;
        mRecyclerView.setTag(R.id.item_click_support, this);
        mRecyclerView.addOnChildAttachStateChangeListener(mAttachListener);
    }

    public static ItemClickSupport addTo(RecyclerView view) {
        ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
        if (support == null) {
            support = new ItemClickSupport(view);
        }
        return support;
    }

    public static ItemClickSupport removeFrom(RecyclerView view) {
        ItemClickSupport support = (ItemClickSupport) view.getTag(R.id.item_click_support);
        if (support != null) {
            support.detach(view);
        }
        return support;
    }

    public ItemClickSupport setOnItemClickListener(OnItemClickListener listener) {
        mOnItemClickListener = listener;
        return this;
    }

    public ItemClickSupport setOnItemLongClickListener(OnItemLongClickListener listener) {
        mOnItemLongClickListener = listener;
        return this;
    }

    private void detach(RecyclerView view) {
        view.removeOnChildAttachStateChangeListener(mAttachListener);
        view.setTag(R.id.item_click_support, null);
    }

    public interface OnItemClickListener {

        void onItemClicked(RecyclerView recyclerView, int position, View v);
    }

    public interface OnItemLongClickListener {

        boolean onItemLongClicked(RecyclerView recyclerView, int position, View v);
    }
}

接下来,在您定义并绑定recyclerView的活动/片段中,只需执行以下操作

//Here the mRecyclerView is the name of the defined recyclerView
ItemClickSupport.addTo(mRecyclerView).setOnItemClickListener(new ItemClickSupport.OnItemClickListener() {
    @Override
    public void onItemClicked(RecyclerView recyclerView, int position, View v) {
        // do it
    }
});

此外,您需要在res/values文件夹中创建一个ids.xml文件,并在其中定义以下内容。
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <item name="item_click_support" type="id" />
</resources>

我希望这可以帮到你。仍然建议你阅读文章以了解更多相关内容。


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