在Android中同时使用onTouch和onLongClick

8

我正在动态地向父布局添加ImageViews,并在添加的图片上使用onTouch进行缩放操作。

我希望能够通过对其进行onLongPress来删除已添加的视图。

img.setOnLongClickListener(longClickAction);
img.setOnTouchListener(touchAction); 
 

onLongPress:

OnLongClickListener longClickAction = new OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        parentLayout.removeView((ImageView)v);
        return false;
    }
};

onTouch:

OnTouchListener touchAction = new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        ImageView i = (ImageView)v;

        // Perform zoom operation onTouch of ImageView
        zoom(i, event);
        return true; 
    }
};

为什么只有onTouch事件起作用?

如何让它们都起作用?

我应该怎么做才能移除添加的视图?


@Siddhesh,请参考我的下面的答案,问题会得到解决。 - Pankaj Lilan
6个回答

21

onTouch方法总是在向视图分派事件的初始状态下被调用。当你长按你的视图时,这仍然会首先调用onTouch方法,由于你在onTouch方法中返回了true(表示你已经处理了此事件,不应再进一步分派),因此不会调用onLongPress方法。要解决此问题,需要在onTouch方法中返回false


5
但是这样会同时调用onTouchonLongPress,如果onLongPress的意思是不要调用onTouch该怎么办? - Luis A. Florit
@LuisA.Florit:你找到解决方法了吗?我也遇到了同样的问题,onTouch和onLongPress同时被调用。 - Tejas

2
正如@asenovm所讨论的那样,onTouch()总是被调用,因为它是将事件分派到视图的初始状态,但是如果我们在onTouch()中返回值false,那么两者都会像魔术般地工作,问题也会得到解决。 编辑:我的建议是,不要同时实现OnLongClickListener()OnTouch()函数,而是尝试在双击事件中使用OnLongClickListener()函数。 您可以通过以下方式实现双击:
int i = 0;
btn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    i++;
    Handler handler = new Handler();
    Runnable r = new Runnable() {

        @Override
        public void run() {
            i = 0;
        }
    };

    if (i == 1) {
        //Single click
        handler.postDelayed(r, 250);
    } else if (i == 2) {
        //Double click
        i = 0;
        ShowDailog();
    }


  }
});

1
尝试一下,对我来说它运行得很好。
boolean isMoving= false;

yourView.setOnTouchListener(new View.OnTouchListener(){
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_MOVE) {
            isMoving = true;
            Log.i("isMoving:", "true");
        }
        if(event.getAction()==MotionEvent.ACTION_UP){
            isMoving=false;
            Log.i("isMoving:","false");
        }
        return false;
    }
});
yourView.setOnLongClickListener(new View.OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        if(!isMoving){
            //do onlongclick event here
        }
        return true;
    }
});;

0

0

你不能通过同时使用 setOnLongClickListener 和 setOnTouchListener 来实现这个功能,因为当你在 onTouch 方法中返回 true 时,它会认为你已经处理了所有的触摸事件。你可以通过延迟 post 并在超时后调用方法来实现长按,但你需要检查是否仍在按下或者 action up 是否被触发。也许这段代码片段可以帮助你:

 mBinding.iv2.setOnTouchListener(object : View.OnTouchListener {

        var stillPress = false
        override fun onTouch(view: View?, motionEvent: MotionEvent?): Boolean {
            if(motionEvent?.action == MotionEvent.ACTION_DOWN){
                 stillPress = true
                Handler(Looper.getMainLooper()).postDelayed({
                    if(stillPress)
                        zoomImageFromThumb(view!!,R.drawable.ic_baseline_adb_24)
                },1000)
            }

            if(motionEvent?.action == MotionEvent.ACTION_UP){
                stillPress = false
                mBinding.expandedImage.performClick()
            }
            return true

        }
    })

0
如果你需要手指保持静止,那么在 Kotlin 中最简单的方法是这样的:
在 onCreateView 中:
view.setOnTouchListener(this)
view.setOnClickListener(this)
view.setOnLongClickListener {
    if (! isFingerMoving) {
        Toast.makeText(activity, "Long click detected", Toast.LENGTH_LONG).show()
        //do something
    }
    false
}

onTouch中:

fun onTouch(v: View?, event: MotionEvent): Boolean {
    when (event.actionMasked) {
        MotionEvent.ACTION_DOWN -> {
            isFingerMoving = false
            lastTouchX = event.getX(0)
            lastTouchY = event.getY(0)
            ...
        }
        
        MotionEvent.ACTION_MOVE -> {
            val deltaX = (x - lastTouchX) * event.xPrecision
            val deltaY = (y - lastTouchY) * event.yPrecision
            if ((deltaX.absoluteValue > 0.1) || (deltaY.absoluteValue > 0.1)) 
                isFingerMoving = true            
            ...                 
        }
    }
    return false
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接