android - 在 RecyclerView 中的一行内单击处理按钮

标签 android android-recyclerview

我正在使用以下代码来处理行点击。 (source)

static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {

    private GestureDetector gestureDetector;
    private ClickListener clickListener;

    public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
        this.clickListener = clickListener;
        gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                return true;
            }

            @Override
            public void onLongPress(MotionEvent e) {
                View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
                if (child != null && clickListener != null) {
                    clickListener.onLongClick(child, recyclerView.getChildPosition(child));
                }
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {

        View child = rv.findChildViewUnder(e.getX(), e.getY());
        if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
            clickListener.onClick(child, rv.getChildPosition(child));
        }
        return false;
    }

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

但是,如果我想在每一行上说一个删除按钮,这可行。我不确定如何用这个来实现。

我将 OnClick 监听器附加到删除按钮,该按钮有效(删除行),但它也会触发整行的 onclick。

如果单击单个按钮,任何人都可以帮助我避免全行单击。

谢谢。

最佳答案

这就是我在 recyclerView 中处理多个 onClick 事件的方式:

编辑:已更新以包含回调(如其他评论中所述)。我在 ViewHolder 中使用了 WeakReference 来消除潜在的内存泄漏。

定义接口(interface):

public interface ClickListener {

    void onPositionClicked(int position);
    
    void onLongClicked(int position);
}

然后是适配器:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
    
    private final ClickListener listener;
    private final List<MyItems> itemsList;

    public MyAdapter(List<MyItems> itemsList, ClickListener listener) {
        this.listener = listener;
        this.itemsList = itemsList;
    }

    @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.my_row_layout), parent, false), listener);
    }

    @Override public void onBindViewHolder(MyViewHolder holder, int position) {
        // bind layout and data etc..
    }

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

    public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {

        private ImageView iconImageView;
        private TextView iconTextView;
        private WeakReference<ClickListener> listenerRef;

        public MyViewHolder(final View itemView, ClickListener listener) {
            super(itemView);

            listenerRef = new WeakReference<>(listener);
            iconImageView = (ImageView) itemView.findViewById(R.id.myRecyclerImageView);
            iconTextView = (TextView) itemView.findViewById(R.id.myRecyclerTextView);

            itemView.setOnClickListener(this);
            iconTextView.setOnClickListener(this);
            iconImageView.setOnLongClickListener(this);
        }

        // onClick Listener for view
        @Override
        public void onClick(View v) {

            if (v.getId() == iconTextView.getId()) {
                Toast.makeText(v.getContext(), "ITEM PRESSED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(v.getContext(), "ROW PRESSED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
            }
            
            listenerRef.get().onPositionClicked(getAdapterPosition());
        }


        //onLongClickListener for view
        @Override
        public boolean onLongClick(View v) {

            final AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
            builder.setTitle("Hello Dialog")
                    .setMessage("LONG CLICK DIALOG WINDOW FOR ICON " + String.valueOf(getAdapterPosition()))
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {

                        }
                    });

            builder.create().show();
            listenerRef.get().onLongClicked(getAdapterPosition());
            return true;
        }
    }
}

然后在您的 Activity/fragment 中 - 无论您可以实现什么:Clicklistener - 或匿名类,如果您愿意的话:

MyAdapter adapter = new MyAdapter(myItems, new ClickListener() {
            @Override public void onPositionClicked(int position) {
                // callback performed on click
            }

            @Override public void onLongClicked(int position) {
                // callback performed on click
            }
        });

要获取点击了哪个项目,您需要匹配 View ID,即 v.getId() == whateverItem.getId()

希望这种方法有所帮助!

关于android - 在 RecyclerView 中的一行内单击处理按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30284067/

相关文章:

android-fragments - nestedscrollview 内 RecyclerView 的 onBindViewHolder 立即为所有项目调用

android - AppBarLayout 并不总是在向下滚动时重新进入

android - 嵌套 ScrollView 中的两个 Recyclerview

java - Android Canvas drawLine 未在 MainActivity 上绘制

android - 单击 recyclerView 时打开文件(pdf,mp3,mp4,...)

java - 可扩展 ListView 中的 Android 数据绑定(bind)

android - Android 上标的顶部被剪裁

android - Android:如何像YouTube一样创建ScrollView?

android - Cordova android 插件调试

android - 如何在android中使用volley发送(POST)xml文件