Search code examples
androidimageviewviewflipperonfling

OnClick ImageView with OnFling ViewFlipper


I have a ViewFlipper which holds a single ImageView. i want to be able to swipe to change the image / view, and click the image to play a sound.

I have a GestureDetector which is handling OnFling to change the view. I tried to put an onClickListener to the imageview, which worked but stopped the OnFling working.

Lastly, I added an onSingleTapConfirmed to my GestureDetector. This worked, however it registers a click anywhere in the Activity not just the ImageView.

Can anyone suggest how to narrow down the onSingleTapConfirmed to just work on the Imageview?

Here's my code so far:

 class MyGestureDetector extends SimpleOnGestureListener {
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        try {
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                return false;
            // right to left swipe
            if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                Log.v("Swipe", "Right to Left");

                viewFlipper.setInAnimation(slideLeftIn);
                viewFlipper.setOutAnimation(slideLeftOut);
                viewFlipper.addView(nextImage(true));

                viewFlipper.showNext();

            }  else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                Log.v("Swipe", "Left to Right");

                viewFlipper.setInAnimation(slideRightIn);
                viewFlipper.setOutAnimation(slideRightOut);
                viewFlipper.addView(nextImage(false));
                viewFlipper.showNext();
            }
        } catch (Exception e) {
            // nothing
        }
        return false;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent e)
    {
        // TODO Auto-generated method stub

        Log.v("SingleTap", "OnSingleTapConfirmed Run");

        return super.onSingleTapConfirmed(e);   

    }    

}

private View nextImage(boolean righttoleft) {
    ImageView imgv1 = new ImageView(this);

    if(righttoleft == true)
    {

            Uri image = Uri.parse("android.resource://com.owentech.brainybaby/drawable/" + variables.letters[variables.currentpos]);
            imgv1.setImageURI(image);
            imgv1.setScaleType(ImageView.ScaleType.CENTER_INSIDE);

    return imgv1;
}

Solution

  • I had encountered this problem in the past.

    Maybe you can try to implement single tap by setting an OnTouchListener to ViewFlipper, thus, the ViewFlipper will be the only touch event receiver. Then write the playing sound code in onTouch function. Finally, set onTouch function's return value to false for the sake of keeping the onFling working.

    viewFlipper.setOnTouchListener(new OnTouchListener()
    {
          @Override
          public boolean onTouch(View view, MotionEvent e) {
              // TODO Auto-generated method stub
              switch(e.getActionMasked())
              {
                 case MotionEvent.ACTION_DOWN:
                      //put the playing sound code here.
                      break;
              }
              return false;  //means that the listener dosen't consume the event
          }
    }
    );
    

    It's just a simple solution to solve this problem. If you want to achieve more complicated function such as avoiding sound playing when finger is swiping on the screen to change the view, you have to take more effort to distinguish gestures, e.g. calculate the time between ACTION_DOWN event and ACTION_UP event and play the sound if it's less than 300ms.

    I hope this will be helpful to you. :)