【问题标题】:onClickListener doesn't work with RecyclerView itemsonClickListener 不适用于 RecyclerView 项目
【发布时间】:2016-10-11 09:30:01
【问题描述】:

我的主要活动(包含 RecyclerView 的活动)如下所示:

myList = (RecyclerView) findViewById(R.id.my_list);
myAdapter = new MyAdapter(this, getData());
myList.setAdapter(myAdapter);
myList.setLayoutManager(new LinearLayoutManager(this));

然后我有一个 MyViewHolder,

public class MyViewHolder extends RecyclerView.ViewHolder {
    ...
    public Button addButton;
    public View root;
    public MyViewHolder(View itemView) {
        super(itemView);
        ...
        addButton = (Button) itemView.findViewById(R.id.add_button);
        root = itemView;
    }
    ...
}

然后是适配器

public class MyAdapter extends RecyclerView.Adapter <MyViewHolder>{
    private LayoutInflater myInflater;

    List<MyModel> data = Collections.emptyList();

    Context context;

    public MyAdapter (Context context, List<MyModel> data) {
        myInflater = LayoutInflater.from(context);
        this.data = data;
        this.context = context;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = myInflater.inflate(R.layout.my_item, parent, false);
        MyViewHolder myViewHolder = new MyViewHolder(view);
        return myViewHolder;
    }

    @Override
    public void onBindViewHolder(final MyViewHolder holder, int position) {
        ...
        holder.addButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("Hello", "Added");
            }
        });
        holder.root.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d("Hello", "Rooted");
            }
        });
    }
...
}

从上面可以看出,我有一个 RecyclerView 项,它有一个按钮作为子项。单击 childButton 时,onClickListener 工作,我得到 Added 打印。但是当我单击整个项目(根)时,什么也没有发生。为什么root onClickListener 不起作用?

我是一个真正的 Android 初学者,所以我不确定我哪里出错了。

编辑

my_item.xml 看起来像:

<LinearLayout>
    <RelativeLayout
         android:clickable="true"> <-- this is the problem as correctly pointed out by user13
        <RelativeLayout>
            <TextView>
            <LinearLayout>
                <TextView>
                <TextView>
                <TextView>
            </LinearLayout>
        </RelativeLayout>
        <RelativeLayout>
            <Button>
            <Button>
        </RelativeLayout>
    </RelativeLayout>
</LinearLayout>

【问题讨论】:

    标签: android android-recyclerview onclicklistener


    【解决方案1】:

    您可能需要在 my_item.xml 中将以下属性添加到您的根 LinearLayout

    android:clickable="true"
    

    【讨论】:

      【解决方案2】:

      您需要添加onTouch监听器,在您的项目中添加以下类

      ClickListener.java

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

      RecyclerTouchListener .java

      public 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) {
              }
      
              @Override
              public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept)    {
      
              }
          }
      

      现在你设置适配器的地方像这样使用这个类

        myList .addOnItemTouchListener(new RecyclerTouchListener(this, myList , new ClickListener() {
                  @Override
                  public void onClick(View view, int position) {
                    //do your stuff on click
                  }
      
                  @Override
                  public void onLongClick(View view, int position) {
                      //do your stuff on ling click
                  }
              }));
      
          }
      

      【讨论】:

      • 这是一种处理方式,但原问题中的代码sn-p只是一个大项目的sn-p,它目前在onBind方法中添加了onClickListener。您建议的方法虽然可能更优化,但现在无法集成。无论如何谢谢:)
      猜你喜欢
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多