我正在尝试在同一视图上实现两个手势(点按和缩放/缩放)
这是我的onTouchListener
代码:
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int touchCount = event.getPointerCount();
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
{
if(touchCount==1)
{
//do Autofocus here
Log.v(TAG, "touchCount == 1");
gestureDetector.onTouchEvent(event);
}
}
break;
case MotionEvent.ACTION_MOVE:
{
if(touchCount==2)
{
//scale gesture
Log.v(TAG, "touchCount == 2");
scaleGestureDetector.onTouchEvent(event);
}
}
break;
}
手势代码:
scaleGestureDetector = new ScaleGestureDetector(getActivity(), new ScaleGestureListener());
gestureDetector = new GestureDetector(new Gesture());
private class ScaleGestureListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
float scale = detector.getScaleFactor();
Log.v(TAG, "scale = "+scale);
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
// TODO Auto-generated method stub
super.onScaleEnd(detector);
}
}
private class Gesture extends GestureDetector.SimpleOnGestureListener
{
@Override
public boolean onDown(MotionEvent event) {
// TODO Auto-generated method stub
Log.v(TAG, "onDown ");
return super.onDown(event);
}
};
问题:
即使我尝试使用Down Event
,它始终会在我的Gesture
听众中触发Pinch Gesture
。
非常感谢任何帮助。
答案 0 :(得分:0)
我用以下逻辑解决了这个问题:
我带了一个标志isPinchInProgress
并在我的Tap Gesture Listener中执行了一些延迟的代码,检查isPinchInProgress
标志是真还是假。
boolean isPinchInProgress = false;
private class ScaleGestureListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
// TODO Auto-generated method stub
Log.d(TAG, "scaling started !");
isPinchInProgress = true;
return true;
}
@Override
public boolean onScale(ScaleGestureDetector detector) {
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
// TODO Auto-generated method stub
Log.d(TAG, "scaling end !");
isPinchInProgress = false;
super.onScaleEnd(detector);
}
}
private class Gesture extends GestureDetector.SimpleOnGestureListener
{
@Override
public boolean onSingleTapConfirmed(final MotionEvent event) {
// TODO Auto-generated method stub
Log.v(TAG, "onSingleTapConfirmed ");
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
if(!isPinchInProgress)
{
//My code to be executed
}
}
}, 270);
return true;
}
@Override
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
return onSingleTapConfirmed(e);
}
}
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
int touchCount = event.getPointerCount();
if(v instanceof MY_CUSTOM_VIEW_CLASS)
{
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
{
if(touchCount == 2)
{
return false;
}
else if(touchCount==1)
{
//do Autofocus here
Log.v(TAG, "touchCount == 1");
gestureDetector.onTouchEvent(event);
return true;
}
}
break;
case MotionEvent.ACTION_MOVE:
{
if(touchCount==2)
{
//scale gesture
Log.v(TAG, "touchCount == 2");
scaleGestureDetector.onTouchEvent(event);
return true;
}
else if(touchCount == 1)
{
return false;
}
}
break;
case MotionEvent.ACTION_UP:
{
scaleGestureDetector.onTouchEvent(event);
return true;
}
}
}
return false;
}
我希望这有助于任何面临同样问题的人。
答案 1 :(得分:0)
我遇到了同样的问题并改进了一些 Salman Kwakwani 的回答:
class ScaleAndClickGestureDetector(val context: Context, val listener: Listener) : ScaleGestureDetector.OnScaleGestureListener {
companion object {
private const val DELAY_BEFORE_CLICK_CONFIRMED = 270L
}
interface Listener {
fun onClick()
fun onScale(scaleFactor: Float)
}
private val scaleGestureDetector = ScaleGestureDetector(context, this)
private var pinching = false
override fun onScale(detector: ScaleGestureDetector?) = false
override fun onScaleBegin(detector: ScaleGestureDetector?): Boolean {
pinching = true
return true
}
override fun onScaleEnd(detector: ScaleGestureDetector?) {
pinching = false
detector?.scaleFactor?.let {
listener.onScale(it)
}
}
fun onTouchEvent(event: MotionEvent): Boolean {
return if (event.pointerCount > 1) {
scaleGestureDetector.onTouchEvent(event)
} else if (event.action == MotionEvent.ACTION_DOWN && !pinching) {
Handler().postDelayed({
if (!pinching) {
listener.onClick()
}
}, DELAY_BEFORE_CLICK_CONFIRMED)
true
} else {
false
}
}
}
然后使用它:
val scaleAndClickGestureDetector = ScaleAndClickGestureDetector(context, object : ScaleAndClickGestureDetector.Listener {
override fun onClick() {}
override fun onScale(scaleFactor: Float) {}
})
yourView.setOnTouchListener { v, event ->
scaleAndClickGestureDetector.onTouchEvent(event)
}