Android onTouchListener 警告:当检测到点击时 onTouch 应该调用 View#performClick

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24952312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:58:01  来源:igfitidea点击:

onTouchListener warning: onTouch should call View#performClick when a click is detected

androidontouchlistener

提问by Trzy Gracje

I have created a onTouchListener. Unfortunately onTouch() method throwsme a warning:

我创建了一个onTouchListener. 不幸的是 onTouch() 方法throws给我一个警告:

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

What does it means? I have not found any information about this warn. Here is the full code:

这是什么意思?我没有找到有关此警告的任何信息。这是完整的代码:

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

回答by Secko

Here you go:

干得好:

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

回答by yoAlex5

You can suppress the Lint

您可以抑制 Lint

@SuppressLint("ClickableViewAccessibility")

You should call performClick()inside onTouchEvent().

你应该调用performClick()inside onTouchEvent()

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

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

or

或者

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

        v.performClick();

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

OnTouchflow

OnTouch流动

Read more here

在这里阅读更多

回答by APEXBoi

In case you're not using a Custom Viewwhich explicitly overrides onPerformClick, the warning won't get removed by just following Secko's answer.

如果您没有使用Custom View显式覆盖的onPerformClick,则仅按照 Secko 的回答不会删除警告。

In addition to his answer, for doing the same on classes like android.widget.Buttonor Buttonyou need to make a simple custom view which extends the target view.

除了他的回答之外,为了在像android.widget.Buttonor 之类的类上做同样的事情,Button你需要制作一个简单的自定义视图来扩展目标视图。

Example :

例子 :

The Custom View Class:

自定义视图类:

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:

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

Current problems : Warning gets resolved by IDE, but can't see this practically performing click action on a real Android Device.

当前问题:警告已由 IDE 解决,但无法在真正的 Android 设备上实际执行点击操作。

EDIT: Fixed getting the click event : Use View.setPressed(boolean)

编辑:固定获取点击事件:使用View.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;
    }

回答by Clairton Luz

just call performClick method, like this:

只需调用 performClick 方法,如下所示:

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

回答by Osvel Alvarez Jacomino

I had a similar issue with a MultiTouchListenerand solved it implementing a GestureDetectorand listening for a SingleTap(This does not remove the warning but starts to triggering onClickevents on my view)

我有一个类似的问题,MultiTouchListener并解决了它实现 aGestureDetector并侦听 a SingleTap(这不会消除警告,但开始onClick在我的视图中触发事件)

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

    }

}