Peringatan onTouchListener: onTouch harus memanggil View # performClick saat klik terdeteksi

109

Saya telah membuat onTouchListener. Sayangnya onTouch () memberi throwssaya peringatan:

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

Apa artinya? Saya belum menemukan informasi apapun tentang peringatan ini. Ini kode lengkapnya:

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;
    }   
});
Trzy Gracje
sumber
17
Anda ingin menyingkirkan peringatan panggil saja v.performClick(). Implementasinya akan memainkan sedikit suara (jika Anda mengaktifkannya di perangkat Anda) dan memanggil onClickListener, yang mungkin belum Anda timpa
Blackbelt
Jawaban Anda benar. Terima kasih
Trzy Gracje

Jawaban:

129

Ini dia:

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;
}
Secko
sumber
14
bukankah seharusnya itu dipanggil hanya ketika event == MotionEvent.Action_UP, atau sesuatu seperti itu? Selain itu, bukankah mengembalikan "salah" sebenarnya memanggil metode klik asli, jadi Anda seharusnya mengembalikan "benar" sebagai gantinya?
Pengembang android
@longilong Nah jika Anda mau, Anda juga dapat mengaturnya untuk menggunakan switch-case, tetapi secara logis sama ...
pengembang android
3
Saya memiliki peringatan serupa. Tapi skenario saya sedikit berbeda karena saya menyetel OnTouchListener anonim saat menyiapkan RecyclerView (memanggil myRecyclerView.setOnTouchListener. Android Studio menandai seluruh kelas anonim dengan peringatan serupa dan bahkan jika saya menambahkan v.performClick peringatan tetap ada.
fr4gus
8
jika kita mengembalikan false dari metode ini, kita tidak perlu memanggil performClick, bukan? Dalam kasus ini, saya tidak mengerti mengapa peringatan lint masih ada
Jiechao Wang
9
Tidak melakukan apa pun untuk memperbaiki peringatan tersebut.
TheLibrarian
2

Anda dapat menekan Lint

@SuppressLint("ClickableViewAccessibility")

Anda harus menelepon ke performClick()dalam onTouchEvent().

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

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

atau

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

        v.performClick();

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

OnTouch mengalir

Baca lebih lanjut di sini

yoAlex5
sumber
1
Anda tidak perlu menimpa performClick(). Silakan bagikan kode Anda
yoAlex5
1

Jika Anda tidak menggunakan Custom Viewyang secara eksplisit menimpa onPerformClick, peringatan tidak akan dihapus hanya dengan mengikuti jawaban Secko.

Selain jawabannya, untuk melakukan hal yang sama pada kelas seperti android.widget.Buttonatau ButtonAnda perlu membuat tampilan kustom sederhana yang memperluas tampilan target.

Contoh:

Kelas Tampilan Kustom:

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" />

Jawa :

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

Masalah saat ini: Peringatan diselesaikan oleh IDE, tetapi tidak dapat melihat tindakan klik yang melakukan tindakan ini secara praktis pada Perangkat Android yang sebenarnya.

EDIT : Tetap mendapatkan acara klik: GunakanView.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;
    }
APEXBoi
sumber
0

panggil saja metode performClick, seperti ini:

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

Saya memiliki masalah serupa dengan MultiTouchListenerdan menyelesaikannya dengan menerapkan GestureDetectordan mendengarkan SingleTap(Ini tidak menghapus peringatan tetapi mulai memicu onClickperistiwa pada pandangan saya)

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

    }

}
Osvel Alvarez Jacomino
sumber