Android: handling clicks on image view inside recy

2019-02-20 06:56发布

问题:

I am trying to capture the clicks on ImageView which is enclosed inside the RecyclerView item. I have implemented RecyclerView.OnItemTouchListener and has gesture detector process the motion events for normal clicks and long press on RecyclerView item.

Since I want to have the same touch framework to process touch event on child views inside the RecylcerView item, I have set View.OnTouchListener with the image view as well, overriding the onTouch implementation returning true hoping that the touch shall be consumed by the ImageView when it gets clicked.

I am intentionally returning false in onInterceptTouchEvent always from the RecyclerView, hoping the child views process the event first and if none of them consumes then RecyclerView's item view shall handle the gesture event for clicks during onTouchEvent handling.

With the above understanding I am able to receive touch events on the ImageView when clicked on it.

The problem is that, when I click on the RecyclerView item outside ImageView, RecyclerView's onTouchEvent is not getting called at all. my understanding of the touch framework is that if child views doesn't process the touch event, the RecyclerView's onTouchEvent should get a chance to process the same. However this is not what i am able to achieve.

Can anyone suggest what is happening behind and what is the correct way to process click events for the above?

回答1:

This will solve your problem:

public class OnItemClickListener implements View.OnClickListener {
    private int position;
    private OnItemClickCallback onItemClickCallback;

    public OnItemClickListener(int position, OnItemClickCallback onItemClickCallback) {
        this.position = position;
        this.onItemClickCallback = onItemClickCallback;
    }

    @Override
    public void onClick(View view) {
        onItemClickCallback.onItemClicked(view, position);
    }

    public interface OnItemClickCallback {
        void onItemClicked(View view, int position);
    }
}

Get an instance of 'OnItemClickCallback' interface and put it in your activity or fragment:

private OnItemClickListener.OnItemClickCallback onItemClickCallback = new OnItemClickListener.OnItemClickCallback() {
    @Override
    public void onItemClicked(View view, int position) {
        // switch(view.getId()) ...
    }
};

Then, pass that callback to your recyclerView:

recyclerView.setAdapter(new SimpleStringRecyclerViewAdapter(Arrays.asList("1", "2", "3"), onItemClickCallback));

Finally, this would be your adapter:

public class SimpleStringRecyclerViewAdapter extends RecyclerView.Adapter<SimpleStringRecyclerViewAdapter.ViewHolder> {
    private List<String> mValues;
    private OnItemClickListener.OnItemClickCallback onItemClickCallback;

    public SimpleStringRecyclerViewAdapter(List<String> items, OnItemClickListener.OnItemClickCallback onItemClickCallback) {
        mValues = items;
        this.onItemClickCallback = onItemClickCallback;
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {
        public final View mView;
        public final TextView mTextView;

        public ViewHolder(View view) {
            super(view);
            mView = view;
            mTextView = (TextView) view.findViewById(R.id.txt_title);
        }
    }

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

    @Override
    public void onBindViewHolder(final ViewHolder holder, final int position) {
        holder.mTextView.setText(mValues.get(position));
        holder.mView.setOnClickListener(new OnItemClickListener(position, onItemClickCallback));
        holder.mTextView.setOnClickListener(new OnItemClickListener(position, onItemClickCallback));
    }

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