Avertissement onTouchListener: onTouch doit appeler View # performClick lorsqu'un clic est détecté


109

J'ai créé un fichier onTouchListener. Malheureusement, onTouch () throwsm'avertit:

com/calculator/activitys/Calculator$1#onTouch should call View#performClick when a click is detected

Qu'est-ce que ça veut dire? Je n'ai trouvé aucune information sur cet avertissement. Voici le code complet:

LinearLayout llCalculatorContent = (LinearLayout) fragmentView.findViewById(R.id.calculator_content);

llCalculatorContent.setOnTouchListener(new View.OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Tools.hideKeyboard(getActivity(), getView());
        getView().clearFocus();
        return false;
    }   
});

17
vous voulez vous débarrasser de l'avertissement, appelez simplement v.performClick(). L'implémentation jouera un petit son (si vous l'avez activée sur votre appareil) et appellera le onClickListener, que vous n'avez probablement pas écrasé
Blackbelt

Votre réponse était correcte. Merci
Trzy Gracje

Réponses:


129

Voici:

public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        //some code....
        break;
    case MotionEvent.ACTION_UP:
        v.performClick();
        break;
    default:
        break;
    }
    return true;
}

14
ne devrait-il pas être appelé uniquement lorsque l'événement == MotionEvent.Action_UP, ou quelque chose comme ça? De plus, le retour de "false" n'appellerait-il pas la méthode de clic d'origine, vous devriez donc retourner "true" à la place?
développeur android

@longilong Eh bien, si vous le souhaitez, vous pouvez également le configurer pour utiliser le boîtier de commutation, mais c'est logiquement la même chose ...
Développeur Android

3
J'ai un avertissement similaire. Mais mon scénario est un peu différent puisque je configure un OnTouchListener anonyme lors de la configuration de RecyclerView (appelant myRecyclerView.setOnTouchListener. Android Studio marque toute la classe anonyme avec un avertissement similaire et même si j'ajoute v.performClick, l'avertissement reste.
fr4gus

8
si nous retournons false de cette méthode, nous ne devrions pas être obligés d'appeler performClick, non? Dans ce cas, je ne comprends pas pourquoi l'avertissement de peluche est toujours là
Jiechao Wang

9
Ne fait rien pour corriger l'avertissement.
TheLibrarian

2

Vous pouvez supprimer la charpie

@SuppressLint("ClickableViewAccessibility")

Vous devriez appeler à l' performClick()intérieur onTouchEvent().

@Override
public boolean onTouchEvent(MotionEvent event) {
    //A logic 

    performClick();
    return super.onTouchEvent(event);
}

ou

findViewById(R.id.view1).setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {

        v.performClick();

        return v.onTouchEvent(event);
    }
});

OnTouch couler

En savoir plus ici


1
Vous n'avez pas à passer outre performClick(). S'il vous plaît partager votre code
yoAlex5

1

Si vous n'utilisez pas un Custom Viewqui remplace explicitement onPerformClick, l'avertissement ne sera pas supprimé en suivant simplement la réponse de Secko.

En plus de sa réponse, pour faire la même chose sur des classes comme android.widget.Buttonou Buttonvous devez faire une simple vue personnalisée qui étend la vue cible.

Exemple :

La classe de vue personnalisée:

public class UselessButton extends AppCompatButton {
    public UselessButton(Context context) {
        super(context);
    }

    public UselessButton(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public UselessButton(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean performClick() {
        return super.performClick();
    }
}

XML :

<stackoverflow.onEarth.UselessButton
    android:id="@+id/left"
    android:layout_width="60dp"
    android:layout_height="60dp"
    android:layout_marginStart="16dp"
    android:layout_marginTop="16dp"
    android:layout_marginEnd="8dp"
    android:layout_marginBottom="8dp"
    android:background="@drawable/left"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.16"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintBaseline_toBaselineOf="@+id/right"
    app:layout_constraintVertical_bias="0.5" />

Java :

    left.setOnTouchListener((v, event) -> {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            enLeft = 1;
            enRight = 0;
            return true;
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            enLeft = 0;
            v.performClick();
            return false;
        } else {
            return false;
        }
    });

Problèmes actuels: l'avertissement est résolu par l'EDI, mais ne peut pas voir cette action de clic pratiquement en cours d'exécution sur un vrai appareil Android.

EDIT : Correction de l'obtention de l'événement de clic: utilisationView.setPressed(boolean)

down.setOnTouchListener((v, event) -> {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        enFront = 0;
        enBack = 1;
        left.setPressed(true);
        return true;
    } else if (event.getAction() == MotionEvent.ACTION_UP) {
        enBack = 0;
        v.performClick();
        v.setPressed(false);
        return false;
    } else {
        return false;
    }

0

appelez simplement la méthode performClick, comme ceci:

@Override
public boolean onTouch(View v, MotionEvent event) {
    v.performClick();
    Tools.hideKeyboard(getActivity(), getView());
    getView().clearFocus();
    return false;
}   

0

J'ai eu un problème similaire avec a MultiTouchListeneret je l'ai résolu en implémentant a GestureDetectoret en écoutant un SingleTap(cela ne supprime pas l'avertissement mais commence à déclencher des onClickévénements sur ma vue)

class TouchListener(context: Context) : MultiTouchListener() {

    private var tochedView: View? = null
    private var mGestureDetector = CustomGestureDetector()
    private var gestureDetector: GestureDetector = GestureDetector(context, mGestureDetector)

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouch(view: View?, event: MotionEvent?): Boolean {
        val aux = super.onTouch(view, event)

        tochedView = view
        gestureDetector.onTouchEvent(event)

        return aux
    }

    private inner class CustomGestureDetector: GestureDetector.SimpleOnGestureListener() {

        override fun onSingleTapUp(e: MotionEvent?): Boolean {
            // this will be called even when a double tap is
            tochedView?.performClick()
            return super.onSingleTapUp(e)
        }

        override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
            // this will only be called after the detector is confident that the
            // user's first tap is not followed by a second tap leading to a double-tap gesture.
            tochedView?.performClick()
            return super.onSingleTapConfirmed(e)
        }

    }

}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.