简体   繁体   English

适配器内部的RecyclerView onItemClickListener和View.onClickListener

[英]RecyclerView onItemClickListener and View.onClickListener inside adapter

i'm developing a simple File Manager. 我正在开发一个简单的文件管理器。 This File Manager is inside a Fragment and, obviously, it use a RecyclerView to show folders and files. 这个文件管理器在一个Fragment中,很明显,它使用RecyclerView来显示文件夹和文件。 The layout that manage the row of list is composed by: 1 ImageView, 1 TextView (to show folder/file name) and one ImageView to select options (such as: rename, delete, etc.). 管理列表行的布局由以下组成:1个ImageView,1个TextView(以显示文件夹/文件名)和一个ImageView以选择选项(例如:重命名,删除等)。

To manage click on RecyclerView i implemented a custom OnItemClickListener interface. 为了管理RecyclerView,我实现了自定义的OnItemClickListener接口。 The code is: 代码是:

public class OnRecyclerItemClickListener implements RecyclerView.OnItemTouchListener {  

    GestureDetector gestureDetector;
    OnItemClickListener listener;

    public interface OnItemClickListener {
        public void onItemClick(View view, int position);
    }

    public OnRecyclerItemClickListener(Context context, OnItemClickListener listener) {
       this.listener = listener;

       gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
           @Override
           public boolean onSingleTapUp(MotionEvent e) {
               return true;
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
        View childView = view.findChildViewUnder(e.getX(), e.getY());
        if(childView != null && listener != null && gestureDetector.onTouchEvent(e)) {
            ((OnItemClickListener) listener).onItemClick(childView, view.getChildAdapterPosition(childView));
        }

        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
        // TODO Auto-generated method stub      
    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean arg0) {
        // TODO Auto-generated method stub      
    }
}

So, in the Fragment: 因此,在片段中:

recyclerView.addOnItemTouchListener(new OnRecyclerItemClickListener(activity, new OnRecyclerItemClickListener.OnItemClickListener() {
    @Override
    public void onItemClick(View view, int position) {
        // TODO Auto-generated method stub                  

        }
    }));

All works fine but now i have a problem: to manage the options when the user click on ImageView don't work properly because the RecyclerView.OnItemClickListener win on imageView.setOnClickListener. 一切正常,但现在我有一个问题:当用户单击ImageView时无法管理选项,因为RecyclerView.OnItemClickListener在imageView.setOnClickListener上获胜。 When the user click on the ImageView a PopupMenu is showed BUT always disappear because occur simultaneously RecyclerView.OnItemClickListener AND ImageView.OnClickListener. 当用户单击ImageView时,会显示PopupMenu,但始终消失,因为同时发生RecyclerView.OnItemClickListener和ImageView.OnClickListener。 The first win to the second. 第一赢到第二。 How can i solve this? 我该如何解决?

You should change your click functionality to being handled within the ViewHolder you could then choose where to place your click listener. 您应该将点击功能更改为在ViewHolder中处理,然后可以选择将点击侦听器放置在何处。 Doing this will allow you to place a clickable view inside your layout with the clickable ImageView being over the top of that. 这样做将允许您将可点击视图放置在布局内,而可点击ImageView位于其上方。 Below is a short example of doing this. 以下是执行此操作的简短示例。 You will need to fill in the gaps, as well as setting up the Interface properly. 您将需要填补空白,并正确设置Interface Let me know if you need any more help. 让我知道您是否需要更多帮助。

public interface ViewHolderListener {
    void itemClicked(int position);
    void imageClicked(int position);
}

public void fillView(ViewHolderItem item) {
        clickableView.setOnClickListener(new View.OnClickListener {
                viewHolderListener.itemClicked(getAdapterPosition());
    });

        yourImage.setOnClickListener(new View.OnClickListener {
            viewHolderListener.imageClicked(getAdapterPosition());
    });
}

At First you need to understand that the whole view will be come under Recycler View (Imageview +textview ). 首先,您需要了解整个视图将位于“回收者视图”下(Imageview + textview)。 Now If you want to have two separate events for both Recycler view and ImageView click the ideal way should be you write them off in Adapter class of the Recyler view rather than creating an interface. 现在,如果要对Recycler视图和ImageView同时拥有两个单独的事件,请单击理想的方法是将它们在Recyler视图的Adapter类中注销,而不是创建接口。

In the adapter class you write the onclick listener of the recycler view itself. 在适配器类中,编写回收者视图本身的onclick侦听器。 like: 喜欢:

view.setonClickListener(new View.OnClickListener(){ onClick){} } view.setonClickListener(new View.OnClickListener(){onClick){}}

and for ImageView you write something like 对于ImageView,您编写类似

imageview.setonClickListener(new View.OnClickListener(){ onClick){ // This code will not call --View.onClick of your Recycler View--} } imageview.setonClickListener(new View.OnClickListener(){onClick){//此代码不会调用回收者视图的--View.onClick--}}

It is the only way that both can operate separately. 这是两者可以分别操作的唯一方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM