android - 使用 GestureDetectorCompat 的奇怪行为
问题描述
我有一个 DoubleTapButton 类有一个奇怪的问题。
该按钮在 main_activity.xml 文件中定义,包括 onClick、MainActivity.DoStuff。
问题是当单击按钮时,按钮在 GestureDetector.OnDoubleTapListener 知道单击或双击之前调用 MainActivity.DoStuff。
我的 DoubleTapButton 使用 setTag() 设置按钮标签,doStuff 方法读取标签。标签设置正确,但直到调用 doStuff 方法之后。为时已晚,无法使用。
我想我在这里遗漏了一步,但我这几天一直在扰乱这段代码,似乎无法让它正常工作。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<kenz.a.testbutton.DoubleTapButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Do Stuff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:onClick="doStuff"/>
类 DoubleTapButton
package kenz.a.testbutton;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import androidx.appcompat.widget.AppCompatButton;
import androidx.core.view.GestureDetectorCompat;
public class DoubleTapButton
extends AppCompatButton
implements GestureDetector.OnGestureListener,
GestureDetector.OnDoubleTapListener {
private String TAG = "KENZ DoubleTapButton";
private GestureDetectorCompat myDetector;
public DoubleTapButton(Context context, AttributeSet attrs) {
super(context, attrs);
myDetector = new GestureDetectorCompat(context,this);
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return myDetector.onTouchEvent(event);
}
});
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
Log.d(TAG, "onSingleTapConfirmed: Setting View Tag("+getId()+") Single");
setTag(getId(),"Single");
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
Log.d(TAG, "onDoubleTap: Setting View Tag("+getId()+") Double");
setTag(getId(),"Double");
return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
}
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
}
类 MainActivity
package kenz.a.testbutton;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
String TAG = "Kenz MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void doStuff(View view) {
String s;
if(view.getTag(view.getId())==null)s="Null";
else s = view.getTag(view.getId()).toString();
Log.d(TAG, "doStuff: "+view.getTag(view.getId()));
Toast.makeText(this,s,Toast.LENGTH_SHORT).show();
}
}
LogCat 输出
07-25 23:16:15.154 26047-26047/kenz.a.testbutton D/Kenz MainActivity: doStuff: null
07-25 23:16:15.334 26047-26047/kenz.a.testbutton D/KENZ DoubleTapButton: onSingleTapConfirmed: Setting View Tag(-1) Single
07-25 23:16:21.450 26047-26047/kenz.a.testbutton D/Kenz MainActivity: doStuff: Single
07-25 23:16:21.580 26047-26047/kenz.a.testbutton D/KENZ DoubleTapButton: onDoubleTap: Setting View Tag(-1) Double
07-25 23:16:25.074 26047-26047/kenz.a.testbutton D/Kenz MainActivity: doStuff: Double
07-25 23:16:25.204 26047-26047/kenz.a.testbutton D/KENZ DoubleTapButton: onDoubleTap: Setting View Tag(-1) Double
07-25 23:16:27.436 26047-26047/kenz.a.testbutton D/Kenz MainActivity: doStuff: Double
07-25 23:16:27.646 26047-26047/kenz.a.testbutton D/KENZ DoubleTapButton: onSingleTapConfirmed: Setting View Tag(-1) Single
似乎 onClick 在 GestureDetector.OnDoubleTapListener 知道单击或双击之前调用了 MainActivity.doStuff(View view) 。我想我在这里遗漏了一步,但我这几天一直在扰乱这段代码,似乎无法让它正常工作。
解决方案
解决了。
使用 LongPress 而不是双击并删除了 DoubleClick 处理程序。根据需要工作。MainActivity.doStuff 现在在标签中使用“Long”或“Single”来获取调用。
我用它来缩放,单击步进缩放,长恢复正常。
长按钮
enter code here
package kenz.a.testbutton;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import androidx.appcompat.widget.AppCompatButton;
import androidx.core.view.GestureDetectorCompat;
public class LongButton
extends AppCompatButton
implements GestureDetector.OnGestureListener {
private String TAG = "KENZ LongButton";
private GestureDetectorCompat mDetector;
Long dtime = System.currentTimeMillis();
public LongButton(Context context, AttributeSet attrs) {
super(context, attrs);
mDetector = new GestureDetectorCompat(context,this);
setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return mDetector.onTouchEvent(event);
}
});
}
@Override
public boolean onDown(MotionEvent e) {
return false;
}
@Override
public void onShowPress(MotionEvent e) {
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
Long curTime = System.currentTimeMillis();
if(curTime-dtime < 200) setTag(getId(),"Double Click");
else {
dtime = System.currentTimeMillis();
setTag(getId(), "Single Click");
}
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}
@Override
public void onLongPress(MotionEvent e) {
Log.d(TAG, "onLongPress: Setting View Tag("+getId()+") Long");
setTag(getId(),"Long Click");
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return false;
}
}
推荐阅读
- java - 看不懂这种java参考
- scala - 如何在 Cassandra Datastax 驱动程序中将 Java 集合转换为 Scala
- mysql - 从 hive 读取数据并将其显示在仪表板上
- javascript - 如何实现需要不断运行的节点应用程序?
- python - 当我尝试访问 wand.image 时出现错误
- c# - 在 Resco SmartGrid 中选择行
- r - Finding total distance moved with for loop
- angularjs - Remove k-button class from kendogrid command buttons
- sql - SQL 使用 Union 和 Group By 将行组合成一行
- javascript - How to get table row data in different table when selecting a checkbox?