Home » Android » android – Can't figure out how to hook fling using ImageViewTouch

android – Can't figure out how to hook fling using ImageViewTouch

Posted by: admin June 15, 2020 Leave a comment

Questions:

I’m using the library (https://github.com/sephiroth74/ImageViewZoom) but I’m having a problem trying to figure out fling. I’ve read the other answers but they don’t show the actual code used to get fling events.

I’ve hooked fling events like this:

 mImage.setOnTouchListener(new OnTouchListener()
 {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
      return gestureDetector.onTouchEvent(event);
 }
 });
 gestureDetector = new GestureDetector(this, new MyGestureDetector(getApplicationContext(), this));

MyGestureDetector extends SimpleOnGestureListener. I then override the onFling method.

The problem with this approach is that it disables the 1 touch and hence the pan functionality. I’m sure there is a better way to hook into fling events (so I can change images) but I’m not sure how -newb 🙁

What I’m looking for is a way to hook this similar to other hooks provided by ImageViewZoom. Like this:

         mImage = (ImageViewTouch) view.findViewById(R.id.image);
    mImage.setOnClickListener(this);

    // set the default image display type
    mImage.setDisplayType( ImageViewTouchBase.DisplayType.FIT_TO_SCREEN );

    mImage.setSingleTapListener( new ImageViewTouch.OnImageViewTouchSingleTapListener()
    {
        @Override
        public void onSingleTapConfirmed()
        {
            Log.d(TAG, "onSingleTapConfirmed");
            setToolbarsVisible(!isToolbarsVisible());
        }
    });
How to&Answers:

Note: I haven’t tested/coded this myself, so it may not work out of the box.

I checked the source code for ImageViewTouch – it uses a SimpleOnGestureListener internally to provide various gesture-based functionality(including single-tap and double-tap hooks). It doesn’t provide a callback for the fling event. So, you will have to code that yourself. Start by defining a new interface, say OnImageViewTouchFlingEventListener inside of/outside of ImageViewTouch.java. For example sake – define it after line 320 of ImageViewTouch.java:

public interface OnImageViewTouchFlingEventListener {

    // Can be defined as `void onFlingEvent(boolean left)` ==> if left==true, user
    // flinged `left-to-right`, else `right-to-left`. Similarly, you can
    // modify the parameters to add checks for up-to-down and down-to-up.
    void onFingEvent();
}

Next, add a member to ImageViewTouch.java after line 31:

private OnImageViewTouchFlingEventListener mFlingEventListener;

Add a public method to initialize mFlingEventListener after line 64:

public void setFlingEventListener( OnImageViewTouchFlingEventListener listener ) {
    mFlingEventListener = listener;
}

Line 261 of ImageViewTouch.java: The method onFling(.....) defines how the ImageView reacts to fling events. Firstly, check whether you agree with the current functionality. For example, you mentioned that you want the fling event to change images. If you look at line 266, the fling event will do nothing if the current scale is 1 – it simply returns false.

How the ImageView acts to a fling (and under what circumstances) is something that you will need to decide. Say, you decide that the fling will change images only when the scale is one – otherwise, it will pan. Then the following modification to line 266 should work:

if (getScale() == 1f) {
    if (mFlingEventListener != null) {
        mFlingEventListener.onFlingEvent();
        return true;
    }
}

In your code, when you set an OnTouchListener on ImageViewTouch, it overtakes all touch functionality afforded by ImageViewTouch’s internal touch/gesture handling – hence no single/double tap callbacks. This is why you cannot implement fling event callback outside of ImageViewTouch.java – well, you can – but then, you’ll need to implement everything other gesture as well.

Changes to your activity code:

The member mFlingEventListener needs to be initialized:

mImage.setFlingEventListener(new ImageViewTouch.OnImageViewTouchFlingEventListener() {
    @Override
    public void onFlingEvent() {
        Log.d(TAG, "onFlingEvent fired");
        // handle change of image
    }
});    

Answer:

It may not be the answer you are looking for but I will give it a try. If you are not obliged to use the library you are currently using I would like to recommend this library which is the best zoomable image view solution I discovered so far. It has following features:

Features

  • Out of the box zooming, using multi-touch and double-tap.
  • Scrolling, with smooth scrolling fling.
  • Works perfectly when using used in a scrolling parent (such as ViewPager).
  • Allows the application to be notified when the displayed Matrix has changed. Useful for when you need to update your UI based on the
    current zoom/scroll position.
  • Allows the application to be notified when the user taps on the Photo.