0

I've an Activity with only 1 image with Pan/Zoom/Rotation system added. I need to implement a double tap on image to add another function to my code, but I can't make it.. I've try to add to my image the setOnClickListener with onClick method but nothing happens although without any code error.

public class LastActivity extends AppCompatActivity
{
ImageView my_View;
float scalediff;
private static final int NONE = 0;
private static final int DRAG = 1;
private static final int ZOOM = 2;
private int mode = NONE;
private float oldDist = 1f;
private float d = 0f;
private float newRot = 0f;

@SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_last);

    my_View = findViewById(R.id.my_View);

    final Bundle mBundle = getIntent().getExtras();

    if (mBundle != null)
    {
        my_View.setImageResource(mBundle.getInt("fullImg"));
    }

    init();

    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int sWidth = size.x;
    int sHeight = size.y;

    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(800, 800);

    my_View.setLayoutParams(layoutParams);

    my_View.setOnTouchListener(new View.OnTouchListener() {
        RelativeLayout.LayoutParams parms;
        int startwidth;
        int startheight;
        float dx = 0, dy = 0, x = 0, y = 0;
        float angle = 0;

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            final ImageView view = (ImageView) v;

            ((BitmapDrawable) view.getDrawable()).setAntiAlias(true);
            switch (event.getAction() & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_DOWN:

                    parms = (RelativeLayout.LayoutParams) view.getLayoutParams();
                    startwidth = parms.width;
                    startheight = parms.height;
                    dx = event.getRawX() - parms.leftMargin;
                    dy = event.getRawY() - parms.topMargin;
                    mode = DRAG;
                    break;

                case MotionEvent.ACTION_POINTER_DOWN:

                    oldDist = spacing(event);
                    if (oldDist > 10f) {
                        mode = ZOOM;
                    }

                    d = rotation(event);

                    break;
                case MotionEvent.ACTION_UP:

                    break;

                case MotionEvent.ACTION_POINTER_UP:

                    mode = NONE;

                    break;
                case MotionEvent.ACTION_MOVE:

                    if (mode == DRAG) {

                        x = event.getRawX();
                        y = event.getRawY();

                        parms.leftMargin = (int) (x - dx);
                        parms.topMargin = (int) (y - dy);

                        parms.rightMargin = 0;
                        parms.bottomMargin = 0;
                        parms.rightMargin = parms.leftMargin + (5 * parms.width);
                        parms.bottomMargin = parms.topMargin + (10 * parms.height);

                        view.setLayoutParams(parms);

                    } else if (mode == ZOOM) {

                        if (event.getPointerCount() == 2) {

                            newRot = rotation(event);
                            angle = newRot - d;

                            x = event.getRawX();
                            y = event.getRawY();

                            float newDist = spacing(event);
                            if (newDist > 10f) {
                                float scale = newDist / oldDist * view.getScaleX();
                                if (scale > 0.6) {
                                    scalediff = scale;
                                    view.setScaleX(scale);
                                    view.setScaleY(scale);

                                }
                            }

                            view.animate().rotationBy(angle).setDuration(0).setInterpolator(new LinearInterpolator()).start();

                            x = event.getRawX();
                            y = event.getRawY();

                            parms.leftMargin = (int) ((x - dx) + scalediff);
                            parms.topMargin = (int) ((y - dy) + scalediff);

                            parms.rightMargin = 0;
                            parms.bottomMargin = 0;
                            parms.rightMargin = parms.leftMargin + (5 * parms.width);
                            parms.bottomMargin = parms.topMargin + (10 * parms.height);

                            view.setLayoutParams(parms);
                        }
                    }
                    break;
            }
            return true;
        }
    });

}

private void init()
{
    my_View = findViewById(R.id.my_View);
}

private float spacing(MotionEvent event)
{
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    return (float) Math.sqrt(x * x + y * y);
}

private float rotation(MotionEvent event)
{
    double delta_x = (event.getX(0) - event.getX(1));
    double delta_y = (event.getY(0) - event.getY(1));
    double radians = Math.atan2(delta_y, delta_x);
    return (float) Math.toDegrees(radians);
}
}

How can implements the double tap to the image without doing damage to the original code?

this is the onClick method

int c = 0;

my_View.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
    c++;
    Handler handler = new Handler();
    Runnable run = new Runnable()
    {
        @Override
        public void run()
        {
            c = 0;
        }
    };

    handler.postDelayed(run,350);
    if (c == 2)
    {
        // event code
    }
}
});

2 Answers2

1

you can implement a gesture detector adapting this answer:

GestureDetector gestureDetector = new GestureDetector(context, new GestureListener());
}

// skipping measure calculation and drawing

// delegate the event to the gesture detector

@Override
public boolean onTouchEvent(MotionEvent e) {
    return gestureDetector.onTouchEvent(e);
}

//since you already have the previous bookean for your original code to work, try changing "return true" (of your on touch event) to "return gestureDetector.onTouchEvent(e)"

private class GestureListener extends GestureDetector.SimpleOnGestureListener {

    @Override
    public boolean onDown(MotionEvent e) {
        return true;
    }
    // event when double tap occurs
    @Override
    public boolean onDoubleTap(MotionEvent e) {
        float x = e.getX();
        float y = e.getY();

        //double tapped

        return true;
    }
}

If you have problems with the ggeasture detector getting the event and your original touch listener not reacting, just get all the other events in the geaturelistener (copying your code to the apprpiate event (which tou will need to add to onDown and onDoubleClicked, to do this you probably need to change the "extends simple geasture listener" to a extends gesture listener)

miquelvir
  • 1,748
  • 1
  • 7
  • 21
  • thank 4 info but can't add GestureListener() to my code, i receive errors.. the only way I find is add onClick method (I've add code on question now) but don't know why don't work... (this method in other activity works fine). – Ronny Westwood Aug 25 '18 at 13:48
  • because you already have a OnTouchListener maybe…. see last paragraph of my answer – miquelvir Aug 26 '18 at 15:23
0

The better and working solution for me is adding the birdman answer of this post into my code....