MichaelAndroidNewbie
MichaelAndroidNewbie

Reputation: 695

How do I implement ScaleGestureDetector in a custom view

I am a complete beginner and have trouble adapting some tutorial code. This activity (gameScreen) should hold a custom view named MapView which extends ImageView and should allow zooming. As it stands, the Image does not fill the screen as intended (the screen is set to landscape and it leaves blank space on the left and right side of the image). The view/activity also does not seem to be allowing the zoom feature to work. Any help appreciated! Thank you!

Here is the gameScreen.java activity:

package com.games.michael.treasureseeker;

import android.app.Activity;
import android.os.Bundle;

import java.util.Random;

public class GameScreen extends Activity {

    private MapView iv;

    @Override
    protected void onCreate(Bundle savedInstanceState)    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.game_screen);
    }
}

Here is the game_screen.xml layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" android:layout_height="fill_parent"

    android:id="@+id/gameBackground">

    <TextView
        android:id="@+id/directions"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:textColor="@color/white"
        android:background="@color/black"
        android:paddingLeft="6dip"
        android:paddingRight="6dip"
        />

    <com.games.michael.treasureseeker.MapView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/imageView"
        android:src="@drawable/pirate_map_2"
        android:layout_below="@+id/directions"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />
</RelativeLayout>

Here is the custom view class MapView.java:

package com.games.michael.treasureseeker;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.widget.ImageView;

public class MapView extends ImageView {
    private ScaleGestureDetector SGD;
    private float scale = 1.f;
    private Matrix matrix = new Matrix();

    public MapView(Context context) {
        super(context);
        SGD = new ScaleGestureDetector(getContext(), new ScaleListener());
    }

    public MapView(Context context, AttributeSet attrs) {
        super(context, attrs);
        SGD = new ScaleGestureDetector(getContext(), new ScaleListener());
    }

    public MapView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        SGD = new ScaleGestureDetector(getContext(), new ScaleListener());
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        SGD.onTouchEvent(ev);
        return super.onTouchEvent(ev);
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvas.save();
        canvas.scale(scale, scale);

        MapView.this.setImageResource(R.drawable.pirate_map_2);
        canvas.restore();
    }

    private class ScaleListener extends
               ScaleGestureDetector.SimpleOnScaleGestureListener {
        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            scale *= detector.getScaleFactor();
            scale = Math.max(0.1f, Math.min(scale, 5.0f));
            //matrix.setScale(scale, scale);
            //this.setImageMatrix(matrix);
            invalidate();
            return true;
        }
    }
}

Here is attrs_map_view.xml:

<resources>
    <declare-styleable name="MapView">
        <attr name="exampleString" format="string" />
        <attr name="exampleDimension" format="dimension" />
        <attr name="exampleColor" format="color" />
        <attr name="exampleDrawable" format="color|reference" />
    </declare-styleable>
</resources>

Edit:

I put a toast in the onScale method, when I ran the code and used the onScale gesture the code was activated and the toast was displayed. For some reason the ImageView just won't zoom :...

It seems that the problem lies in the distinction between this project and the many tutorials online. The difference is that I want to scale a file image. I cannot find an example of this online or understand why this will not work, even after many hours of trying. Any further information or suggestions would be most welcome!

Edit: Bump! I am desperate and can't solve this! If anyone could help that would be great!

Upvotes: 2

Views: 1745

Answers (1)

Jayadev
Jayadev

Reputation: 201

You have to specify particular actions inside onTouchEvent(). Write a switch case for MotionEvents ACTION_DOWN, ACTION_MOVE, ACTION_UP,ACTION_POINTER_DOWN, ACTION_POINTER_UP. That will allow zooming or dragging. Please go through this documentation from google Responding to Touch Events.

Hope this helps :)

Upvotes: 1

Related Questions