Android: Custome ImageView
<p>Not sure if anyone can help me with this but I'm trying to add touch functionality to an image by creating a custome ImageView, however when I run it I am getting a Null point exception in the logcat. My code is as follow:</p>

<pre><code>TouchImageView.java

package com.android.wayfinder;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.widget.ImageView;

public class TouchImageView extends ImageView { 

Matrix matrix = new Matrix(); 

// We can be in one of these 3 states 
static final int NONE = 0; 
static final int DRAG = 1; 
static final int ZOOM = 2; 
int mode = NONE; 

// Remember some things for zooming 
PointF last = new PointF(); 
PointF start = new PointF(); 
float minScale = 1f; 
float maxScale = 3f; 
float[] m; 

float redundantXSpace, redundantYSpace; 

float width, height; 
static final int CLICK = 3; 
float saveScale = 1f; 
float right, bottom, origWidth, origHeight, bmWidth, bmHeight; 

ScaleGestureDetector mScaleDetector; 

Context context; 

public TouchImageView(Context context) { 
    super(context); 
    super.setClickable(true); 
    this.context = context; 
    mScaleDetector = new ScaleGestureDetector(context, new ScaleListener()); 
    matrix.setTranslate(1f, 1f); 
    m = new float[9]; 
    setImageMatrix(matrix); 
    setScaleType(ScaleType.MATRIX); 

    setOnTouchListener(new OnTouchListener() { 

        public boolean onTouch(View v, MotionEvent event) { 
            mScaleDetector.onTouchEvent(event); 

            matrix.getValues(m); 
            float x = m[Matrix.MTRANS_X]; 
            float y = m[Matrix.MTRANS_Y]; 
            PointF curr = new PointF(event.getX(), event.getY()); 

            switch (event.getAction()) { 
                case MotionEvent.ACTION_DOWN: 
                    last.set(event.getX(), event.getY()); 
                    start.set(last); 
                    mode = DRAG; 
                    break; 
                case MotionEvent.ACTION_MOVE: 
                    if (mode == DRAG) { 
                        float deltaX = curr.x - last.x; 
                        float deltaY = curr.y - last.y; 
                        float scaleWidth = Math.round(origWidth * saveScale); 
                        float scaleHeight = Math.round(origHeight * saveScale); 
                        if (scaleWidth &lt; width) { 
                            deltaX = 0; 
                            if (y + deltaY &gt; 0) 
                                deltaY = -y; 
                            else if (y + deltaY &lt; -bottom) 
                                deltaY = -(y + bottom);  
                        } else if (scaleHeight &lt; height) { 
                            deltaY = 0; 
                            if (x + deltaX &gt; 0) 
                                deltaX = -x; 
                            else if (x + deltaX &lt; -right) 
                                deltaX = -(x + right); 
                        } else { 
                            if (x + deltaX &gt; 0) 
                                deltaX = -x; 
                            else if (x + deltaX &lt; -right) 
                                deltaX = -(x + right); 

                            if (y + deltaY &gt; 0) 
                                deltaY = -y; 
                            else if (y + deltaY &lt; -bottom) 
                                deltaY = -(y + bottom); 
                        } 
                        matrix.postTranslate(deltaX, deltaY); 
                        last.set(curr.x, curr.y); 
                    } 
                    break; 

                case MotionEvent.ACTION_UP: 
                    mode = NONE; 
                    int xDiff = (int) Math.abs(curr.x - start.x); 
                    int yDiff = (int) Math.abs(curr.y - start.y); 
                    if (xDiff &lt; CLICK &amp;&amp; yDiff &lt; CLICK) 
                        performClick(); 
                    break; 

                case MotionEvent.ACTION_POINTER_UP: 
                    mode = NONE; 
                    break; 
            } 
            setImageMatrix(matrix); 
            invalidate(); 
            return true; // indicate event was handled 
        } 

    }); 
} 

@Override 
public void setImageBitmap(Bitmap bm) {  
    super.setImageBitmap(bm); 
    bmWidth = bm.getWidth(); 
    bmHeight = bm.getHeight(); 
} 

public void setMaxZoom(float x) 
{ 
    maxScale = x; 
} 

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
    @Override 
    public boolean onScaleBegin(ScaleGestureDetector detector) { 
        mode = ZOOM; 
        return true; 
    } 

    @Override 
    public boolean onScale(ScaleGestureDetector detector) { 
        float mScaleFactor = (float)Math.min(Math.max(.95f, detector.getScaleFactor()), 1.05); 
        float origScale = saveScale; 
        saveScale *= mScaleFactor; 
        if (saveScale &gt; maxScale) { 
            saveScale = maxScale; 
            mScaleFactor = maxScale / origScale; 
        } else if (saveScale &lt; minScale) { 
            saveScale = minScale; 
            mScaleFactor = minScale / origScale; 
        } 
        right = width * saveScale - width - (2 * redundantXSpace * saveScale); 
        bottom = height * saveScale - height - (2 * redundantYSpace * saveScale); 
        if (origWidth * saveScale &lt;= width || origHeight * saveScale &lt;= height) { 
            matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2); 
            if (mScaleFactor &lt; 1) { 
                matrix.getValues(m); 
                float x = m[Matrix.MTRANS_X]; 
                float y = m[Matrix.MTRANS_Y]; 
                if (mScaleFactor &lt; 1) { 
                    if (Math.round(origWidth * saveScale) &lt; width) { 
                        if (y &lt; -bottom) 
                            matrix.postTranslate(0, -(y + bottom)); 
                        else if (y &gt; 0) 
                            matrix.postTranslate(0, -y); 
                    } else { 
                        if (x &lt; -right)  
                            matrix.postTranslate(-(x + right), 0); 
                        else if (x &gt; 0)  
                            matrix.postTranslate(-x, 0); 
                    } 
                } 
            } 
        } else { 
            matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY()); 
            matrix.getValues(m); 
            float x = m[Matrix.MTRANS_X]; 
            float y = m[Matrix.MTRANS_Y]; 
            if (mScaleFactor &lt; 1) { 
                if (x &lt; -right)  
                    matrix.postTranslate(-(x + right), 0); 
                else if (x &gt; 0)  
                    matrix.postTranslate(-x, 0); 
                if (y &lt; -bottom) 
                    matrix.postTranslate(0, -(y + bottom)); 
                else if (y &gt; 0) 
                    matrix.postTranslate(0, -y); 
            } 
        } 
        return true; 

    } 
} 

@Override 
protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) 
{ 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    width = MeasureSpec.getSize(widthMeasureSpec); 
    height = MeasureSpec.getSize(heightMeasureSpec); 
    //Fit to screen. 
    float scale; 
    float scaleX =  (float)width / (float)bmWidth; 
    float scaleY = (float)height / (float)bmHeight; 
    scale = Math.min(scaleX, scaleY); 
    matrix.setScale(scale, scale); 
    setImageMatrix(matrix); 
    saveScale = 1f; 

    // Center the image 
    redundantYSpace = (float)height - (scale * (float)bmHeight) ; 
    redundantXSpace = (float)width - (scale * (float)bmWidth); 
    redundantYSpace /= (float)2; 
    redundantXSpace /= (float)2; 

    matrix.postTranslate(redundantXSpace, redundantYSpace); 

    origWidth = width - 2 * redundantXSpace; 
    origHeight = height - 2 * redundantYSpace; 
    right = width * saveScale - width - (2 * redundantXSpace * saveScale); 
    bottom = height * saveScale - height - (2 * redundantYSpace * saveScale); 
    setImageMatrix(matrix); 
} 

}



ImageView.xml

&lt;?xml version="1.0" encoding="utf-8"?&gt;

&lt;com.android.wayfinder.TouchImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/arasnalaoi"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/aras_na_laoi" /&gt;


Activity:

public class ImageActivity extends Activity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


            TouchImageView touch = (TouchImageView) this.findViewById(R.id.arasnalaoi);
            touch.setImageBitmap(BitmapFactory.decodeResource(this.getResources(), R.drawable.aras_na_laoi));
            touch.setMaxZoom(4f);
            setContentView(touch);

        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

    }

}


The null pointer exception is pointing at the line: touch.setImageBitmap... 

I'm absolutely stumpt so any help would be greatly appreciated. 

Shaw
</code></pre>
