Le bouton Android a appelé setOnTouchListener mais ne remplace pas performClick


113

Lorsque j'essaie d'ajouter onTouchListner()à un bouton, cela me donne le

Button a appelé setOnTouchListener mais ne remplace pas performClick

avertissement. Quelqu'un sait-il comment y remédier?

1

btnleftclick.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        return false;
    }
});

Erreur:

La vue personnalisée a appelé setOnTouchListener mais ne remplace pas performClick Si une vue qui remplace onTouchEvent ou utilise un OnTouchListener n'implémente pas également performClick et l'appelle lorsque des clics sont détectés, la vue peut ne pas gérer correctement les actions d'accessibilité. La logique de gestion des actions de clic doit idéalement être placée dans View # performClick car certains services d'accessibilité invoquent performClick lorsqu'une action de clic doit se produire.


La vue personnalisée ImageViewa appelé setOnTouchListener mais ne remplace pas performClick Si une vue qui remplace onTouchEvent ou utilise un OnTouchListener n'implémente pas également performClick et l'appelle lorsque des clics sont détectés, la vue peut ne pas gérer correctement les actions d'accessibilité. La logique de gestion des actions de clic doit idéalement être placée dans View # performClick car certains services d'accessibilité invoquent performClick lorsqu'une action de clic doit se produire.
kas

Veuillez consulter ma réponse ici: stackoverflow.com/questions/47170075/…
lambda

Réponses:


134

Cet avertissement apparaît parce qu'Android veut vous rappeler de penser aux personnes aveugles ou malvoyantes qui peuvent utiliser votre application. Je vous suggère de regarder cette vidéo pour un aperçu rapide de ce à quoi cela ressemble.

Les vues de l' interface utilisateur standard (comme Button, TextView, etc.) sont tous mis en place pour fournir aux utilisateurs des aveugles avec des commentaires appropriés grâce à des services d' accessibilité. Lorsque vous essayez de gérer vous-même les événements tactiles, vous risquez d'oublier de fournir ce retour d'information. C'est à cela que sert l'avertissement.

Option 1: créer une vue personnalisée

La gestion des événements tactiles est normalement effectuée dans une vue personnalisée. Ne rejetez pas cette option trop rapidement. Ce n'est pas vraiment si difficile. Voici un exemple complet de TextViewqui est remplacé pour gérer les événements tactiles:

public class CustomTextView extends AppCompatTextView {

    public CustomTextView(Context context) {
        super(context);
    }

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

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                return true;

            case MotionEvent.ACTION_UP:
                performClick();
                return true;
        }
        return false;
    }

    // Because we call this from onTouchEvent, this code will be executed for both
    // normal touch events and for when the system calls this using Accessibility
    @Override
    public boolean performClick() {
        super.performClick();
        doSomething();
        return true;
    }

    private void doSomething() {
        Toast.makeText(getContext(), "did something", Toast.LENGTH_SHORT).show();
    }
}

Ensuite, vous l'utiliseriez simplement comme ceci:

<com.example.myapp.CustomTextView
    android:id="@+id/textview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="20dp"
    android:text="Click me to do something"/>

Voir mon autre réponse pour plus de détails sur la création d'une vue personnalisée.

Option 2: désactiver l'avertissement

D'autres fois, il vaudrait peut-être mieux faire taire l'avertissement. Par exemple, je ne suis pas sûr de ce que vous voulez faire avec un pour Buttonlequel vous avez besoin d'événements tactiles. Si vous deviez faire un bouton personnalisé et appelé performClick()à onTouchEventcomme je l' ai fait ci - dessus pour la coutume TextView, alors il s'appelle chaque fois que deux fois parce que les Buttonappels déjà performClick().

Voici quelques raisons pour lesquelles vous voudrez peut-être simplement faire taire l'avertissement:

  • Le travail que vous effectuez avec votre événement tactile n'est que visuel. Cela n'affecte pas le fonctionnement réel de votre application.
  • Vous avez le cœur froid et ne vous souciez pas de rendre le monde meilleur pour les aveugles.
  • Vous êtes trop paresseux pour copier et coller le code que je vous ai donné dans l'option 1 ci-dessus.

Ajoutez la ligne suivante au début de la méthode pour supprimer l'avertissement:

@SuppressLint("ClickableViewAccessibility")

Par exemple:

@SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button myButton = findViewById(R.id.my_button);
    myButton.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            return false;
        }
    });
}

1
J'utilisais des vues personnalisées en raison de l'utilisation de polices différentes. Comme maintenant dans Api 26 introduit une nouvelle fonctionnalité, les polices en xml et pour les anciennes versions utilisent la bibliothèque de support 26 qui prend en charge jusqu'à Api 16. J'ai donc supprimé toutes les vues personnalisées. Et cet avertissement stupide apparaît et la solution est de créer à nouveau certaines de ces vues personnalisées pour lesquelles j'utilise setOnTouchListener. hahaha: D So
Strange

19
Je me demande si Google réalise combien d'heures de développeur ils perdent à cause de cela. Je veux dire, ils pourraient peut-être gérer cela dans l'API? passer du temps à sous-classer des vues ou même à chercher comment résoudre son avertissement gaspille beaucoup d'heures.
TatiOverflow

et si vous avez besoin de l' MotionEvent eventobjet dans votre doSomething()méthode? J'ai besoin de vérifier event.getY().
Mateus Gondim

@MateusGondim, je dois dire que je ne suis pas encore très compétent pour la mise en œuvre performClick(). Ma première pensée est que si le event.getY()n'est pas intégral à l'événement de clic réel (c'est-à-dire les effets visuels de l'interface utilisateur), remettez cette logique à onTouchEvent(). Sinon, vous pouvez créer une variable de membre de classe pour stocker la dernière Yvaleur d' action up . Je vous suggère également de consulter le code source de quelques-unes des vues standard afin de voir comment Android l'implémente. J'ai besoin de les étudier davantage moi-même.
Suragch

1
@sisisisi, l'avertissement apparaît lorsque vous remplacez onTouchEvent()mais pas performClick(). Cela peut inclure un balayage ou un clic ou tout autre événement tactile que vous essayez de capturer.
Suragch

17

Solution:

  1. Créez une classe qui étend Button ou la vue que vous utilisez et remplacez performClick ()

    class TouchableButton extends Button {
    
        @Override
        public boolean performClick() {
            // do what you want
            return true;
        }
    }
    
  2. Maintenant, utilisez ce TouchableButton en xml et / ou en code et l'avertissement sera parti!


18
C'est vraiment dégoûtant. N'existe-t-il aucun moyen d'utiliser les vues existantes?
Milk

@Milk Non. android.widget.Buttonest codé en dur, il ne vous permet donc pas de le faire. Et cela semble être très intentionnel de la part de l'équipe de développement Android.
tom_mai78101

11

Avez-vous essayé d'ajouter:

view.performClick()

ou en ajoutant une annotation suppresslint:

@SuppressLint("ClickableViewAccessibility")

?


2
Oui. Ce comeup avec Android Studio 3.0 Edition
KAS

1
D'accord, j'ai une alternative pour corriger cet avertissement. s'il vous plaît voir: stackoverflow.com/questions/47170075/…
lambda

1

Les commandes d'affichage personnalisées peuvent nécessiter un comportement d'événement tactile non standard. Par exemple, un contrôle personnalisé peut utiliser la méthode d'écoute onTouchEvent (MotionEvent) pour détecter les événements ACTION_DOWN et ACTION_UP et déclencher un événement de clic spécial. Afin de maintenir la compatibilité avec les services d'accessibilité, le code qui gère cet événement de clic personnalisé doit effectuer les opérations suivantes:

Générez un AccessibilityEvent approprié pour l'action de clic interprétée. Activez les services d'accessibilité pour effectuer l'action de clic personnalisée pour les utilisateurs qui ne peuvent pas utiliser un écran tactile. Pour gérer ces exigences de manière efficace, votre code doit remplacer la méthode performClick (), qui doit appeler la super-implémentation de cette méthode, puis exécuter toutes les actions requises par l'événement click. Lorsque l'action de clic personnalisée est détectée, ce code doit alors appeler votre méthode performClick ().

https://developer.android.com/guide/topics/ui/accessibility/custom-views#custom-touch-events

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.