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?

Ola Ström
  • 4,136
  • 5
  • 22
  • 41
SANDHYA
  • 771
  • 7
  • 18
  • 27

6 Answers6

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

asenovm
  • 6,397
  • 2
  • 41
  • 52
  • 5
    But then `onTouch` and `onLongPress` will both be called. What about if `onLongPress` means not to call `onTouch`? – Luis A. Florit Mar 17 '14 at 17:47
  • @LuisA.Florit: have you find any solution for this ? same problem with me, both onTouch and onLongPress are called at a time.. – Tejas Jan 02 '15 at 05:38
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();
    }


  }
});
Community
  • 1
  • 1
Pankaj Lilan
  • 4,245
  • 1
  • 29
  • 48
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;
    }
});;
JasonChiu
  • 171
  • 2
  • 6
0

Dynamically remove controls

may help you

using onTouch and onLongClick

Community
  • 1
  • 1
Siddhesh
  • 1,370
  • 11
  • 28
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
}
dvn
  • 1
  • 3
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

        }
    })
Noah Mohamed
  • 114
  • 1
  • 1
  • 8