web-dev-qa-db-fra.com

Gérer l'événement tactile pour les articles à l'intérieur de Recyclerview - android

je construis une simple vue d'ensemble du recyclage avec une mise en page personnalisée (affichage texte et commutateur) et un adaptateur personnalisé.

Mon problème est que je ne peux pas gérer l'événement click pour le commutateur (ce qui le fait basculer son état), j'ai construit un écouteur tactile pour le RecyclerView et il se déclenche chaque fois que je clique sur le Switch.

Après de nombreux essais, l'écouteur tactile se déclenche également, mais je souhaite désactiver l'événement de toucher pour le recyclerView si l'utilisateur clique sur le commutateur.

Voici mon code de mise en page:

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="60.0dip"
Android:layout_weight="1.0"
Android:orientation="horizontal"
Android:paddingLeft="16dp">

<TextView
    Android:id="@+id/category_name"
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:layout_alignParentLeft="true"
    Android:layout_alignParentStart="false"
    Android:layout_centerVertical="true"
    Android:layout_gravity="center_vertical"
    Android:text="Category Name"
    Android:textAppearance="?android:textAppearanceLarge" />

<Android.support.v7.widget.SwitchCompat
    Android:id="@+id/category_switch"
    Android:layout_width="80dp"
    Android:layout_height="wrap_content"
    Android:layout_alignParentEnd="true"
    Android:layout_alignParentRight="true"
    Android:layout_centerVertical="true"
    Android:layout_gravity="center_vertical"
    Android:checked="true"
    Android:clickable="true"
    Android:focusable="false"
    Android:focusableInTouchMode="false"
    Android:paddingRight="16dp" />

</RelativeLayout>

voici mon code d'adaptateur:

public CategoryViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View row = layoutInflater.inflate(R.layout.single_row_category, parent, false);
    CategoryViewHolder holder = new CategoryViewHolder(row);

    return holder;
}

public void onBindViewHolder(CategoryViewHolder holder, final int position) {
    AlarmCategory thisCat = categories.get(position);

    holder.catName.setText(thisCat.getCategoryName());

    holder.catStatus.setChecked(thisCat.isOn());

    holder.catStatus.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            Log.d("fpp", view.getClass().getName() + " is clicked");
            return true;
        }
    });
}

public class CategoryViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener {

    public TextView catName;
    public SwitchCompat catStatus;

    public CategoryViewHolder(View itemView) {
        super(itemView);
        itemView.setOnCreateContextMenuListener(this);

        catName = (TextView) itemView.findViewById(R.id.category_name);
        catStatus = (SwitchCompat) itemView.findViewById(R.id.category_switch);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
        menu.add(0, 1001, 0, "Edit");//groupId, itemId, order, title
        menu.add(0, 1002, 1, "Delete");
    }
}

Et voici mon gestionnaire tactile recyclerView:

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 = recyclerView.findChildViewUnder(e.getX(), e.getY());
        if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
            clickListener.onClick(child, rv.getChildPosition(child));

            Log.d("fpp", child.getClass().getName() + " is clicked");

            return false;
        }

        return false;
    }

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

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}

et dans la méthode onCreate je l'appelle par:

recyclerView.addOnItemTouchListener(new RecyclerTouchListener(this, recyclerView, new ClickListener() {
        @Override
        public void onClick(View view, int position) {
            Intent i = new Intent(CategoriesList.this, AlarmList.class);
            i.putExtra("catID", categories.get(position).getCategoryID());
            startActivity(i);
        }

        @Override
        public void onLongClick(View view, int position) {
            catPos = position;
        }
    }));

Toute aide s'il vous plaît, j'ai déjà essayé beaucoup de solutions mais rien n'a fonctionné pour désolé.

Merci d'avance.

12
Fareed

Une façon consiste à mettre à jour votre support pour gérer tous les clics de vue en interne, par exemple.

public class CategoryViewHolder extends RecyclerView.ViewHolder implements View.OnCreateContextMenuListener, View.OnClickListener, CompoundButton.OnSetCheckedListener {
    public CategoryViewHolder(View itemView) {
        super(itemView);
        itemView.setOnCreateContextMenuListener(this);
        itemView.setOnClickListener(this);

        catName = (TextView) itemView.findViewById(R.id.category_name);
        catStatus = (SwitchCompat) itemView.findViewById(R.id.category_switch);
        catStatus.setOnCheckChangedListener(this);
    }

    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        // deal with catStatus change
    }

    public void onClick(View view) {
        // deal with itemView click
    }
}
8
Dimitar Genov
  1. Créer une classe RecyclerTouchListener

    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) {
    
    }
    
    public interface ClickListener {
        void onClick(View view, int position);
    
        void onLongClick(View view, int position);
      }
    }
    
  2. Utiliser cet écouteur dans l'activité

    recyclerview.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerview, new RecyclerTouchListener.ClickListener() {
            @Override
            public void onClick(View view, int position) {
    
               // Write your code here
    
            }
    
            @Override
            public void onLongClick(View view, int position) {
    
            }
        }));
    
4
rhaldar