onTouch, onLongClick together in Android
Asked Answered
F

7

8

I'm adding ImageViews to parent layout dynamically and performing zoom in/out operations with onTouch on the added image.

I want to remove the added view with an onLongPress of it.

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; 
    }
};

Why do only the onTouch events work?

How can I get them both to work?

What should I do to remove the added view?

Frizzell answered 8/6, 2012 at 10:1 Comment(1)
@Siddhesh follow my below answer, the problem will be solved.Endow
N
21

onTouch is always called for your view since this is the initial state of dispatching the events to the view. When you long press your view this still calls onTouch first and since you return true in onTouch(which means that you've consumed this event and it should not be further dispatched) you won't get onLongPress called. What will do the trick is returning false in onTouch

Naphtha answered 8/6, 2012 at 10:9 Comment(2)
But then onTouch and onLongPress will both be called. What about if onLongPress means not to call onTouch?Jewess
@LuisA.Florit: have you find any solution for this ? same problem with me, both onTouch and onLongPress are called at a time..Doubletongue
E
2

As discussed by @asenovm The onTouch() is always called as it is the initial state of dispatching the events to the view, but if we return value false in onTouch() Then both will work like a charm and the problem will be solved.

Edit: My suggestion to the users is that instead of implementing OnLongClickListener() and OnTouch() together, try using the function of OnLongClickListener() in Double click event.

You can implement Double Click in following ways:

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();
    }


  }
});
Endow answered 31/1, 2017 at 7:55 Comment(0)
T
1

Try this, it works fine for me.

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;
    }
});;
Travesty answered 28/7, 2015 at 6:41 Comment(0)
Z
0

Dynamically remove controls

may help you

using onTouch and onLongClick

Zelikow answered 8/6, 2012 at 10:7 Comment(0)
I
0

If you need finger to be still then the simpliest way to do it in Kotlin is like this

in onCreateView :

view.setOnTouchListener(this)
view.setOnClickListener(this)
view.setOnLongClickListener {
    if (! isFingerMoving) {
        Toast.makeText(activity, "Long click detected", Toast.LENGTH_LONG).show()
        //do something
    }
    false
}

in 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
}
Insubstantial answered 21/7, 2020 at 4:21 Comment(0)
N
0

you cant achive this togither by setOnLongClickListener and setOnTouchListener because when you return true inside onTouch method it assume that you handle all touch events you can achieve long click by post delay and call method after time out but you need to check if is still pressing or action up fired may be this code snapshot help you

 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

        }
    })
Neurosurgery answered 7/2, 2022 at 15:21 Comment(0)
A
0

Use the onLongPress Method from the GestureDetecter class and pass in the onTouch Method of the corresponding View.

Audiovisual answered 10/2 at 18:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.