Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't figure out how to hook fling using ImageViewTouch

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());
        }
    });
like image 678
JustLearningAgain Avatar asked Jul 24 '14 23:07

JustLearningAgain


1 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
    }
});    
like image 63
Vikram Avatar answered Oct 04 '22 01:10

Vikram