如何使用onInterceptTouchEvent从RecyclerView中获取特定视图?

时间:2015-11-13 23:20:37

标签: android android-recyclerview onclicklistener

我一直在寻找,但我仍然找不到任何东西。我试过了

View child = mirecycler.findChildViewUnder(e.getX(), and.getY());  

它只是为了让我的案例中的父级成为CardView容器"行" ,我需要具体TextViewImageView

我想将onClick设置为ImageView而不影响onClick的{​​{1}}。

CardView

4 个答案:

答案 0 :(得分:2)

<TabItem DataContext="{Binding UsbDevicesCollection.Library}"/>

正如你所说,findViewUnder只返回容器。您需要运行另一个传递来查明触摸事件的x和y是否在容器的任何子项上。

public class RecyclerViewItemClickListener implements RecyclerView.OnItemTouchListener { private static final String TAG = RecyclerItemClickListener.class.getSimpleName(); public void setListener(OnItemClickListener mListener) { this.mListener = mListener; } private OnItemClickListener mListener; public RecyclerViewItemClickListener(Context context) { this(context, null); } GestureDetector mGestureDetector; public RecyclerViewItemClickListener(Context context, OnItemClickListener listener) { mListener = listener; mGestureDetector = 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()); View exactView = findExactChild(childView, e.getX(), e.getY()) if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) { mListener.onItemClick(view, exactView, view. view.getChildPosition(childView)); } return false; } @Override public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { } @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { } } public View findExactChild(View childView, int x, int y){ if(!(childView instanceof ViewGroup)) return child; ViewGroup group = (ViewGroup) childView; final int count =group.getChildCount(); for (int i = count - 1; i >= 0; i--) { final View child = group.getChildAt(i); final float translationX = ViewCompat.getTranslationX(child); final float translationY = ViewCompat.getTranslationY(child); if (x >= child.getLeft() + translationX && x <= child.getRight() + translationX && y >= child.getTop() + translationY && y <= child.getBottom() + translationY) { return child; } } return null; } }

这将运行另一个传递以找到确切的孩子。

答案 1 :(得分:0)

因此,一种解决方案是使用onTouchListener。您可以做的是在您的子ImageView上设置onTouchListener并返回true,以便触摸不会传递给视图父级。

答案 2 :(得分:0)

如果你必须使用onInterceptTouchEvent,我不确定我能帮到你。我只在不必管理特定点击时使用它,但也许我的解决方案可以与它一起工作(虽然我没有尝试过)

我将为您提供一个解决方案,使用客户适配器检测点击的位置:

public class SomeRecyclerAdapter extends RecyclerView.Adapter<SomeRecyclerAdapter.SomeListViewHolder> {

    ....

    @Override
public void onBindViewHolder(final SomeViewHolder holder, final int position) {
    SomeItem item = someList.get(position);

    holder.itemView.setTag(item);
    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            SomeListItem item = (SomeListItem) holder.itemView.getTag();
            Toast.makeText(context, "Recycle Click " + item.getName(), Toast.LENGTH_SHORT).show();
        }
    });

    holder.vImage.setTag(item);
    holder.vImage
            .setOnClickListener(new CompoundButton.OnClickListener(){

                @Override
                public void onClick(View v) {
                    SomeListItem item = (SomeItem) holder.vImage.getTag();
                    Toast.makeText(context, item.getName() + " Image Clicked", Toast.LENGTH_SHORT).show();
                }
            });
    ....

    public static class SomeListViewHolder extends RecyclerView.ViewHolder{
        protected ImageView vImage;

        public SomeListViewHolder(View itemView) {
            super(itemView);
            vImage = (ImageView) itemView.findViewById(R.id.tem_some_list);
        }

    }

}

我的例子是如何处理Recycler Item Image中的点击。 我已经尝试过这个解决方案并且它有效,这意味着如果您点击项目(图像除外),它将打印&#34;回收点击...&#34;,如果您点击图像它将打印&#34; ....图片点击&#34;。

也许(未经过测试,但您可以这样做并让我们知道)您可以使用onInterceptTouchEvent作为CardView,使用onClickListener作为图像。

我希望这就是您所寻找的,如果您找到更好的解决方案,请告诉我。

答案 3 :(得分:0)

NBajanca的答案很有效,但在适配器内无法访问主要活动的UI元素,所以解决方案就是使用de an callback。

然后,我们在适配器中的代码看起来像这样。

public class NegociosAdapter extends RecyclerView.Adapter<NegociosAdapter.ViewHolder>  {

   interface MyCallback{
       void Presionofoto(int position);
   }
    private MyCallback callback;

 public NegociosAdapter(ArrayList<Negocios> negociosArrayList,MyCallback callback) {
        this.negociosArrayList = negociosArrayList;
        this.callback=callback;
    }
public static class ViewHolder extends RecyclerView.ViewHolder  {

        public ImageView foto;
        public TextView nombre;

        public ViewHolder(View itemView) {

            super(itemView);
            foto = (ImageView) itemView.findViewById(R.id.foto);
            nombre = (TextView) itemView.findViewById(R.id.txtnombre);

        }
    }
 public void onBindViewHolder(ViewHolder viewHolder, final int position) {

        Negocios rowNegocio = negociosArrayList.get(position);
        viewHolder.nombre.setText(rowNegocio.getNombre());
         viewHolder.foto.setImageBitmap(rowNegocio.getImagen());
         viewHolder.foto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                callback.Presionofoto(position);
               //When click here method "Presionofoto" be running on mainactivity

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

在主要活动中:

public class MainActivity extends AppCompatActivity implements NegociosAdapter.MyCallback{

 NegociosAdapter adapter = new NegociosAdapter(datosResult,this);
            recycler.setAdapter(adapter);

//we have that implement method abstract "Presionofoto"

@Override
public void Presionofoto(final int position) {
//here we can access to UI, this 
 Toast.makeText(getBaseContext(), "Hello From MainActivity", Toast.LENGTH_SHORT).show();
}
}