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

问题描述 投票:0回答:8

我创建了一个

onTouchListener
。不幸的是 onTouch() 方法
throws
我警告:

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

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

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;
    }   
});
android ontouchlistener
8个回答
189
投票

给你:

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

10
投票

检测到点击时,onTouch 应调用 View#performClick

您可以抑制此 Lint 警告

@SuppressLint("ClickableViewAccessibility")

您应该在

performClick()
内致电
onTouchEvent()

@Override
public boolean onTouchEvent(MotionEvent event) {
    //Logic 
    performClick();
    return super.onTouchEvent(event);
}

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

[OnTouch流程]

阅读更多这里


5
投票

如果您没有使用明确覆盖

Custom View
onPerformClick
,则仅按照 Secko 的答案不会删除警告。

除了他的答案之外,为了在

android.widget.Button
Button
等类上执行相同的操作,您需要创建一个扩展目标视图的简单自定义视图。

示例:

自定义视图类:

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

当前问题:IDE 解决了警告,但在真实的 Android 设备上看不到实际执行的单击操作。

编辑:修复了获取点击事件:使用

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

2
投票

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

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

2
投票

我通过使用 Kotlin 扩展解决了这个警告

首先创建扩展(例如ViewExtensions.kt)

fun Button.onTouch(touch: (view: View, motionEvent: MotionEvent) -> Unit) {
    setOnTouchListener { v, event ->
        touch(v,event)
        v.performClick()
        true
    }
}

其次,在您的 Fragment 或 Activity 中创建一个函数

private fun onTouchButton(v: View, event: MotionEvent) {
       /* My Amazing implementation */
}

最后,使用扩展程序

myButton.onTouch { v, event ->
 onTouchButton(v, event)
}

0
投票

我对

MultiTouchListener
也有类似的问题,并通过实现
GestureDetector
并监听
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)
        }

    }

}

0
投票

这是一个超级晚的答案,但我希望它能对某人有所帮助。我不久前遇到了这个警告,我的方法是,创建一个扩展

View.class
的类,然后在该类中创建一个名为
closeKeyboard(View view){}
的公共方法,这就是它的样子:

public class MyTouchEvent extends View {

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

    public void closeKeyboard(View view) {
        view.setOnTouchListener((view1, motionEvent) -> {
            view1.performClick();
       // this is a library handels the closing of keyboard
            UIUtil.hideKeyboard((Activity) getContext());
            return false;
        });
    }

    @Override
    public boolean performClick() {
        super.performClick();
        return true;
    }
}

MainActivity
中,我调用了
closeKeyboard(view)
并使用父布局作为参数,如下所示:

new MyTouchEvent(this).collapseKeyboard(parentLayout);

用于关闭键盘的库

implementation 'net.yslibrary.keyboardvisibilityevent:keyboardvisibilityevent:3.0.0-RC2'

库源


0
投票

我不得不忽略它。我有一个 TouchListener 来引发动画按钮按下(在我的情况下改变颜色)。但我还有一个点击监听器来完成按钮的工作。所以这导致我的点击侦听器再次触发。我在触摸事件(Action_Down、Up等)切换中尝试将其作为默认情况

© www.soinside.com 2019 - 2024. All rights reserved.