OnTouchListener 警告: 检测到单击时,onTouch 应调用 View # PerformClick

我已经创建了一个 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;
}
});
80257 次浏览

给你:

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

如果您没有使用显式覆盖 onPerformClickCustom View,那么仅仅遵循 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;
}

警告: 检测到单击时 onTouch 应调用 View # PerformClick

你可以压制林特

@SuppressLint("ClickableViewAccessibility")

您应该在 onTouchEvent()中调用 performClick()

@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 Flow ]

阅读更多 给你

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

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

我有一个与 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)
}


}


}

这是超级晚的回答,但我希望它能帮助某人。我之前遇到过这样的警告,我的方法是,创建一个扩展 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'

图书馆资料来源

我不得不无视它。我有一个 TouchListener 来引起一个动画按钮按下(在我的例子中改变颜色)。但我也有一个点击监听器来做按钮的工作。所以这导致我的点击监听器再次启动。我在 Touch Events (Action _ Down,Up 等)的切换中将其作为默认情况进行了尝试

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

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

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

其次,在你的片段或活动中创建一个函数

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

最后,使用扩展名

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