web-dev-qa-db-fra.com

Le bouton Android a été défini par setOnTouchListener mais ne remplace pas performClick

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

SetOnTouchListener a été appelé par le bouton, mais ne remplace pas performClick

attention. Est-ce que quelqu'un sait comment résoudre ce problème?

1

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

Erreur:

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

76
kas

Cet avertissement apparaît car Android souhaite vous rappeler de penser aux personnes aveugles ou malvoyantes susceptibles d'utiliser votre application. Je vous suggère de regarder cette vidéo pour un aperçu rapide de la situation.

Les vues standard de l'interface utilisateur (telles que Button, TextView, etc.) sont toutes configurées pour fournir aux utilisateurs aveugles un retour d'informations approprié via les services d'accessibilité. Lorsque vous essayez de gérer vous-même des événements tactiles, vous risquez d'oublier de fournir ces informations. 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 difficile. Voici un exemple complet de TextView qui 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 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: faire taire l'avertissement

D'autres fois, il pourrait être préférable de simplement faire taire l'avertissement. Par exemple, je ne suis pas sûr de ce que vous voulez faire avec un Button pour lequel vous avez besoin d'événements tactiles. Si vous deviez créer un bouton personnalisé appelé performClick() dans onTouchEvent comme ci-dessus pour la personnalisation TextView, il serait alors appelé deux fois à chaque fois car Button appelle 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 est uniquement visuel. Cela n'affecte pas le fonctionnement réel de votre application.
  • Vous avez le coeur froid et ne vous souciez pas de faire de ce monde un meilleur endroit 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;
        }
    });
}
78
Suragch

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 aura disparu!

14
Sjd

Avez-vous essayé d'ajouter:

view.performClick()

ou en ajoutant une annotation suppresslint:

@SuppressLint("ClickableViewAccessibility")

?

9
lambda