如何处理不同的触摸事件,尤其是点击和长按屏幕?
How to probably handle different touch events, especially taps and long press on screen?
我正在制作一个应用程序,您可以在其中触摸屏幕上的特定单词,然后该单词就会发音。但是,当我点击任何单词时,它至少会被发音两次,如果我将手指放在该单词上,它会被发音很多次,我不希望这样。我可以将触摸检测为仅在屏幕上轻按吗?如果用户按住或长按,我希望发生完全不同的事情,例如复制单词。
我试图根据某人的代码来做到这一点,但是 if 和 else 语句 运行!
@Override
public boolean onTouchEvent(MotionEvent event) {
int touchX = Math.round(event.getX());
int touchY = Math.round(event.getY());
long startClickTime = System.currentTimeMillis();
//words are surrounded with rect objects because i'm using the TextRecognition library that Google provided
for(int x=0; x< rects.size();x++) {
if (System.currentTimeMillis() - startClickTime < ViewConfiguration.getTapTimeout()) {
// Touch was a simple tap. Do whatever.
Log.i("TTS", "Touch was a simple tap!");
if (rects.get(x).contains(touchX, touchY)) {
// a word has been clicked -> some code to pronounce the word
return true;
} else {
// Touch was a not a simple tap.
Log.i("TTS", "Touch was a not a simple tap!");
}
}
}
return super.onTouchEvent(event);
}
我也尝试了 onDown()
、onShowPress()
、onSingleTapUp()
和 onLongPress()
方法,但是其中的 none 没有任何作用,我不知道为什么我应该更好地使用 onTouchEvent()
方法吗?
有多种类型MotionEvent Actions您可以通过查看事件的动作来区分它们
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
int touchX = Math.round(event.getX());
int touchY = Math.round(event.getY());
long startClickTime = System.currentTimeMillis();
//words are surrounded with rect objects because i'm using the TextRecognition library that Google provided
for(int x=0; x< rects.size();x++) {
if (System.currentTimeMillis() - startClickTime < ViewConfiguration.getTapTimeout()) {
// Touch was a simple tap. Do whatever.
Log.i("TTS", "Touch was a simple tap!");
if (rects.get(x).contains(touchX, touchY)) {
// a word has been clicked -> some code to pronounce the word
return true;
} else {
// Touch was a not a simple tap.
Log.i("TTS", "Touch was a not a simple tap!");
}
}
}
}
return super.onTouchEvent(event);
}
您可以在单个视图上使用所有 LongClick、Click 和 Touch 侦听器,我不得不偶尔在项目中使用它,所以
我编写了一个实用程序 class 来处理单个视图上的点击、按住(长按)开始和按住结束(释放)。
在
查看
https://github.com/Zohaib-Amir/utility-classes/blob/master/ClickAndHoldManager.java
ClickAndHoldManager manager = new ClickAndHoldManager(myButton);
manager.setClickCallback(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Regular Click
}
});
manager.setHoldCallback(new ClickAndHoldManager.HoldListener() {
@Override
public void holdStarted() {
// this is same as onLongClick
}
@Override
public void holdEnded() {
// LongClick released
}
});
要使用它,只需在构造函数中传递视图并将监听器添加到管理器。
您可以通过在 onTouchEvent 中添加更多事件来自定义它。
(请原谅一些本应私有的方法)
因此,通过结合实现 GestureDetector.OnGestureListener 方法和 onTouchEvent() 方法,我能够完美地处理触摸事件。
private GestureDetectorCompat mDetector;
boolean mIsScrolling;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preview);
// Instantiate the gesture detector with the
// application context and an implementation of
// GestureDetector.OnGestureListener
mDetector = new GestureDetectorCompat(this,this);
//set TouchListener on previewLayout
previewLayout.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (mDetector.onTouchEvent(event)) {
return true;
}
if(event.getAction() == MotionEvent.ACTION_UP) { //when user left his finger up
if(mIsScrolling) { //if it was a scroll action
handleScrollFinished();
mIsScrolling = false; //set mIsScrolling back to false
}
}
return PreviewActivity.super.onTouchEvent(event);
}
});
}
.
@Override
public boolean onDown(MotionEvent event) {
//Do stuff
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent event) {
//So stuff
return true;
}
@Override
public void onLongPress(MotionEvent event) {
//Do stuff
}
@Override
public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
float distanceY) {
mIsScrolling = true;
//Do stuff
return true;
}
private void handleScrollFinished() {
//Do stuff
}
@Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) {
return false; //it has to return false, or I will have to write unnecessary extra code
}
@Override
public void onShowPress(MotionEvent event) {
}
帮助我度过难关的事情:
How to detect when a scroll has ended
我正在制作一个应用程序,您可以在其中触摸屏幕上的特定单词,然后该单词就会发音。但是,当我点击任何单词时,它至少会被发音两次,如果我将手指放在该单词上,它会被发音很多次,我不希望这样。我可以将触摸检测为仅在屏幕上轻按吗?如果用户按住或长按,我希望发生完全不同的事情,例如复制单词。
我试图根据某人的代码来做到这一点,但是 if 和 else 语句 运行!
@Override
public boolean onTouchEvent(MotionEvent event) {
int touchX = Math.round(event.getX());
int touchY = Math.round(event.getY());
long startClickTime = System.currentTimeMillis();
//words are surrounded with rect objects because i'm using the TextRecognition library that Google provided
for(int x=0; x< rects.size();x++) {
if (System.currentTimeMillis() - startClickTime < ViewConfiguration.getTapTimeout()) {
// Touch was a simple tap. Do whatever.
Log.i("TTS", "Touch was a simple tap!");
if (rects.get(x).contains(touchX, touchY)) {
// a word has been clicked -> some code to pronounce the word
return true;
} else {
// Touch was a not a simple tap.
Log.i("TTS", "Touch was a not a simple tap!");
}
}
}
return super.onTouchEvent(event);
}
我也尝试了 onDown()
、onShowPress()
、onSingleTapUp()
和 onLongPress()
方法,但是其中的 none 没有任何作用,我不知道为什么我应该更好地使用 onTouchEvent()
方法吗?
有多种类型MotionEvent Actions您可以通过查看事件的动作来区分它们
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
int touchX = Math.round(event.getX());
int touchY = Math.round(event.getY());
long startClickTime = System.currentTimeMillis();
//words are surrounded with rect objects because i'm using the TextRecognition library that Google provided
for(int x=0; x< rects.size();x++) {
if (System.currentTimeMillis() - startClickTime < ViewConfiguration.getTapTimeout()) {
// Touch was a simple tap. Do whatever.
Log.i("TTS", "Touch was a simple tap!");
if (rects.get(x).contains(touchX, touchY)) {
// a word has been clicked -> some code to pronounce the word
return true;
} else {
// Touch was a not a simple tap.
Log.i("TTS", "Touch was a not a simple tap!");
}
}
}
}
return super.onTouchEvent(event);
}
您可以在单个视图上使用所有 LongClick、Click 和 Touch 侦听器,我不得不偶尔在项目中使用它,所以 我编写了一个实用程序 class 来处理单个视图上的点击、按住(长按)开始和按住结束(释放)。
在
查看https://github.com/Zohaib-Amir/utility-classes/blob/master/ClickAndHoldManager.java
ClickAndHoldManager manager = new ClickAndHoldManager(myButton);
manager.setClickCallback(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Regular Click
}
});
manager.setHoldCallback(new ClickAndHoldManager.HoldListener() {
@Override
public void holdStarted() {
// this is same as onLongClick
}
@Override
public void holdEnded() {
// LongClick released
}
});
要使用它,只需在构造函数中传递视图并将监听器添加到管理器。
您可以通过在 onTouchEvent 中添加更多事件来自定义它。
(请原谅一些本应私有的方法)
因此,通过结合实现 GestureDetector.OnGestureListener 方法和 onTouchEvent() 方法,我能够完美地处理触摸事件。
private GestureDetectorCompat mDetector;
boolean mIsScrolling;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preview);
// Instantiate the gesture detector with the
// application context and an implementation of
// GestureDetector.OnGestureListener
mDetector = new GestureDetectorCompat(this,this);
//set TouchListener on previewLayout
previewLayout.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (mDetector.onTouchEvent(event)) {
return true;
}
if(event.getAction() == MotionEvent.ACTION_UP) { //when user left his finger up
if(mIsScrolling) { //if it was a scroll action
handleScrollFinished();
mIsScrolling = false; //set mIsScrolling back to false
}
}
return PreviewActivity.super.onTouchEvent(event);
}
});
}
.
@Override
public boolean onDown(MotionEvent event) {
//Do stuff
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent event) {
//So stuff
return true;
}
@Override
public void onLongPress(MotionEvent event) {
//Do stuff
}
@Override
public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
float distanceY) {
mIsScrolling = true;
//Do stuff
return true;
}
private void handleScrollFinished() {
//Do stuff
}
@Override
public boolean onFling(MotionEvent event1, MotionEvent event2,
float velocityX, float velocityY) {
return false; //it has to return false, or I will have to write unnecessary extra code
}
@Override
public void onShowPress(MotionEvent event) {
}
帮助我度过难关的事情:
How to detect when a scroll has ended