0

I am attempting to build a game for Android using Android Studio has my IDE. I ran into a barrier that I can't seem to find much information on. I am trying to create an Activity within my project that supports Multi-Directional scrolling/panning (Horizontal, Vertical, AND Diagonal) as well as pinch zooming. If you've ever played Clash of Clans, the main activity is a perfect example. It can zoom in and out, and pan any direction within it's limits.

Things I've Tried

1) Embedded ScrollView

I've tried embedding a horizontal ScrollView withing a Vertical ScrollView (and vice versa), but it wouldn't let me scroll diagonally. The user experience was also very choppy.

2) A "Modified" ScrollView

I've tried the "Modified" ScrollView as suggested here (two directional scroll view), but that didn't work. It either didn't scroll vertically or didn't work at all.

I've seen quite a few questions on StackOverflow and other sites, but no real answers that seem to work. I know this can be done in Unity, but I already have most of my code setup in Android Studio and would like to stay with it. I read somewhere that somebody said I would need to "build your own Renderer" but that went over my head.

Any suggestions are greatly appreciated. Thank you.

Vishal Yadav
  • 3,642
  • 3
  • 25
  • 42
  • all you need is a gesture detector that reads your `MotionEvents` and modifies the world `Matrix` by translating / rotating / scaling - this matrix is then used when drawing your world - you can find a simple `MatrixGestureDetector` [here](https://stackoverflow.com/a/21657145/2252830) – pskink Oct 19 '17 at 04:37

1 Answers1

0

You can override any Layout or ViewGroup to achieve this effect. Then place all your views inside the Layout to get the pan/zoom that you want.

Your onDraw or dispatchDraw should look something like this:

@Override
protected void dispatchDraw(Canvas canvas)
{
    float[] values = new float[9];
    matrix.getValues(values);
    canvas.save();
    canvas.translate(values[Matrix.MTRANS_X], values[Matrix.MTRANS_Y]);
    canvas.scale(values[Matrix.MSCALE_X], values[Matrix.MSCALE_Y]);
    super.dispatchDraw(canvas);
    canvas.restore();
}

Then you have to set up two gesture detectors to intercept scaling and panning.

@Override
public boolean onTouchEvent(MotionEvent event)
{

    matrix.set(savedMatrix);
    boolean gestureDetected = mGestureDetector.onTouchEvent(event);
    if (event.getPointerCount() > 1)
    {
        gestureDetected = mScaleGestureDetector.onTouchEvent(event) | gestureDetected;
        if (checkScaleBounds())
        {
            matrix.postScale(scale, scale, mid.x, mid.y);
        }

    }
    matrix.invert(matrixInverse);
    savedMatrix.set(matrix);
    invalidate();
    return gestureDetected;
}

The full code for a ZoomLayout is available here: https://github.com/maxtower/ZoomLayout/blob/master/app/src/main/java/com/maxtower/testzoomlayout/ZoomLayout.java

mtbomb
  • 1,107
  • 1
  • 13
  • 16