Avviso onTouchListener: onTouch dovrebbe chiamare View # performClick quando viene rilevato un clic


108

Ho creato un file onTouchListener. Purtroppo onTouch () throwsmi metodo un avvertimento:

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

Cosa significa? Non ho trovato alcuna informazione su questo avviso. Ecco il codice completo:

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
se vuoi eliminare l'avvertimento, chiama v.performClick(). L'implementazione riprodurrà un piccolo suono (se lo hai abilitato sul tuo dispositivo) e chiamerà onClickListener, che probabilmente non hai sovrascritto
Blackbelt

La tua risposta era corretta. Grazie
Trzy Gracje

Risposte:


128

Ecco qui:

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
non dovrebbe essere chiamato solo quando l'evento == MotionEvent.Action_UP, o qualcosa del genere? Inoltre, la restituzione di "false" non chiamerebbe effettivamente il metodo di clic originale, quindi dovresti invece restituire "true"?
sviluppatore Android

@longilong Beh, se lo desideri puoi anche impostarlo per utilizzare switch-case, ma logicamente è lo stesso ...
sviluppatore Android

3
Ho un avvertimento simile. Ma il mio scenario è un po 'diverso poiché imposto un OnTouchListener anonimo durante l'impostazione di RecyclerView (chiamando myRecyclerView.setOnTouchListener. Android Studio contrassegna l'intera classe anonima con un avviso simile e anche se aggiungo v.performClick l'avviso rimane.
fr4gus

8
se restituiamo false da questo metodo, non ci dovrebbe essere richiesto di chiamare performClick, giusto? In questo caso non capisco perché l'avviso di lanugine sia ancora presente
Jiechao Wang

9
Non fa nulla per correggere l'avviso.
TheLibrarian

2

Puoi sopprimere il Lint

@SuppressLint("ClickableViewAccessibility")

Dovresti chiamare performClick()dentro onTouchEvent().

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

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

o

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

        v.performClick();

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

OnTouch flusso

Leggi di più qui


1
Non devi eseguire l'override performClick(). Per favore condividi il tuo codice
yoAlex5

1

Nel caso in cui non si utilizzi un Custom Viewoverride esplicito onPerformClick, l'avviso non verrà rimosso semplicemente seguendo la risposta di Secko.

Oltre alla sua risposta, per fare lo stesso su classi come android.widget.Buttono Buttonè necessario creare una semplice visualizzazione personalizzata che estenda la visualizzazione di destinazione.

Esempio :

La classe di visualizzazione personalizzata:

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;
        }
    });

Problemi attuali: l'avviso viene risolto dall'IDE, ma non è possibile visualizzare questa azione di clic che esegue praticamente l'azione su un vero dispositivo Android.

EDIT : corretto il recupero dell'evento clic: UsaView.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

basta chiamare il metodo performClick, in questo modo:

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

0

Ho avuto un problema simile con a MultiTouchListenere l'ho risolto implementando a GestureDetectore ascoltando a SingleTap(questo non rimuove l'avviso ma inizia ad attivare onClickeventi nella mia vista)

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)
        }

    }

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.