我认为需要处理onTouch手势和 onClick事件。实现这个目标的正确方法是什么?
我在视图上设置了onTouchListener
和onClickListener
。每当我触摸视图时,首先触发onTouch
事件,然后触发onClick
。但是,从onTouch
事件处理程序,我必须返回true
或false
。返回true
意味着正在使用该事件,因此android事件系统将不再传播该事件。
因此,永远不会生成onClick
事件,当我在onClick
事件处理程序中返回true
时,至少我的onTouch
侦听器永远不会被触发。另一方面,返回false
没有选项,因为这会阻止onTouch
侦听器接收为识别手势所必需的任何其他事件。解决这个问题的常用方法是什么?
答案 0 :(得分:7)
在你的GestureDetector中,你可以直接调用callOnClick()。 请注意,View.callOnClick API需要API级别15。 试一试。
// Create a Gesturedetector
GestureDetector mGestureDetector = new GestureDetector(context, new MyGestureDetector());
// Add a OnTouchListener into view
m_myViewer.setOnTouchListener(new OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
return mGestureDetector.onTouchEvent(event);
}
});
private class MyGestureDetector extends GestureDetector.SimpleOnGestureListener
{
public boolean onSingleTapUp(MotionEvent e) {
// ---Call it directly---
callOnClick();
return false;
}
public void onLongPress(MotionEvent e) {
}
public boolean onDoubleTap(MotionEvent e) {
return false;
}
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
}
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
}
public void onShowPress(MotionEvent e) {
LogUtil.d(TAG, "onShowPress");
}
public boolean onDown(MotionEvent e) {
// Must return true to get matching events for this down event.
return true;
}
public boolean onScroll(MotionEvent e1, MotionEvent e2, final float distanceX, float distanceY) {
return super.onScroll(e1, e2, distanceX, distanceY);
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
// do something
return super.onFling(e1, e2, velocityX, velocityY);
}
}
答案 1 :(得分:5)
如果您使用onTouchListener
,则不必使用onClickListener
。在onClickListener
它的作用是获取触摸事件并检查事件动作并检测点击。所以,如果你想在onClick
时做一些工作。您可以通过过滤操作在onTouchListener
中执行此操作。
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
//this is touch
}
if (event.getAction() == MotionEvent.ACTION_UP) {
//this is click
}
return false;
}
答案 2 :(得分:4)
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
layOutParams.x = initialX + (int) (event.getRawX() - initialTouchX);
layOutParams.y = initialY + (int) (event.getRawY() - initialTouchY);
break;
case MotionEvent.ACTION_DOWN:
initialX = layOutParams.x;
initialY = layOutParams.y;
initialTouchX = event.getRawX();
initialTouchY = event.getRawY();
if (initialTouchX == event.getRawX() && initialTouchY == event.getRawY()) {
return false;// to handle Click
}
break;
case MotionEvent.ACTION_UP:
if (initialTouchX == event.getRawX() && initialTouchY == event.getRawY()) {
return false;// to handle Click
}
break;
}
return true;
}
};
答案 3 :(得分:0)
isMove = false;
case MotionEvent.ACTION_DOWN:
//Your stuff
isMove = false;
case MotionEvent.ACTION_UP:
if (!isMove || (Xdiff < 10 && Ydiff < 10 ) {
view.performClick; //The check for Xdiff <10 && YDiff< 10 because sometime elements moves a little
even when you just click it
}
case MotionEvent.ACTION_MOVE:
isMove = true;
另一种方法是使用线程。那是在Action_Down上启动一个线程来增加一个计数器。在Action_UP的情况下:停止/中断线程。如果它小于2(根据你的应用程序说或阈值)或者!isMove然后调用点击功能
答案 4 :(得分:0)
我们可以使用基于标志的实现。我们可以在Action_Up中处理滑动/拖动的位置,并使标志为true并返回相同的值。如果在Action_Down中单击或点击相同的句柄并将标志设置为false并返回。
touchAndSwipe=false;
switch(e.getAction()){
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_DOWN:
x1 = e.getX();
break;
case MotionEvent.ACTION_UP:
x2 = e.getX();
float diff= x2-x1;
if(Math.abs(delta)>100){
// Swipe
touchAndSwipe=true;
}else{
touchAndSwipe=false;
}
break;
}
return touchAndSwipe;
答案 5 :(得分:0)
我已经能够在我正在构建的自定义键盘中一起实现OnClick和OnTouch。您可以查看此代码并根据您的上下文对其进行修改,因为您没有包含可用的代码示例。
如果您发布了代码示例,我可以修改我的样本以完成相同的结果供您使用。在Android开发中,上下文就是一切。看看这段代码片段,看看它是否有帮助。否则,请发布您自己的样本,我将进行修改并回复。
View DefaultphaseLay() {
LinearLayout mViewFirstPhase = (LinearLayout) getLayoutInflater().inflate(R.layout.layout_default_phase, parent);
ksOne_btn_LiLay = (LinearLayout) mViewFirstPhase.findViewById(R.id.ksOne_btn_LiLay);
ksOne_btn = (Button) mViewFirstPhase.findViewById(R.id.ksOne_btn);
ksOne_btn.setOnClickListener(mCorkyListener);
ksOne_btn.setFocusableInTouchMode(true);
ksOne_btn.setFocusable(true);
ksOne_btn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
playClick(keyCode);
//v.startAnimation(animScale);
//key_sound.start();
xkeys_lay.setVisibility(View.GONE);
numkeys_lay.setVisibility(View.GONE);
if (Constants.HapticFeedbackConstant) {
myVib.vibrate(Constants.vibration_duration);
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
ksOne_btn.setFocusable(false); //Check This Added This In Attempt to Kill Selector on Action_Up
//playClick(-100);
//key_sound.pause();
}
return false;
}
});
ChangeKeyBackgroundMehods.initChange_Key_Background(ksOne_btn_LiLay);
ChangeFontStyle.initChange_fontStyle(ksOne_btn, getApplicationContext());
ChangeFont_size.initChange_fontSize(ksOne_btn, getApplicationContext());
这适用于alpha或数字输出的上下文,如果事件正在寻找发送或消耗其他需要修改的上下文。
答案 6 :(得分:-1)
我同意jdx,如果你使用onTouchlistener你不需要使用onclicklistener而反之,如果你想触发按钮,图像或textview上的事件点击,那么只需触发onClicklistener。如果你想要一些像拖动和旋转这样的动画,那么使用ontouchlistener获取表面触摸的坐标