Note that there are some explanatory texts on larger screens.

plurals
  1. POCode works on API 8 and can't on API 9 or 10
    primarykey
    data
    text
    <p>For some reason my code works perfectly for Froyo(API 8) but gives me a Stopped Unexpectedly/Force Close error when I try to run it on API 9 or 10, AVD and phones give me the same error message. Any idea as to why? My code for review:</p> <p>All pages look similar to ViewActivity.java. only difference id the drawable called.</p> <p>ViewActivity.java:</p> <pre><code> import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; public class ViewActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //creates view TouchImageView img = new TouchImageView(this); //sets image Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.largeimage1); img.setImageBitmap(image); img.setMaxZoom(3f); setContentView(img); } //Creates the options menu @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.menu.echooptions, menu); return true; } //Starts the chosen menu activity @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.back_item: Intent intentb = new Intent(this, page16.class); startActivity(intentb); return true; case R.id.next_item: Intent intentn = new Intent(this, page2.class); startActivity(intentn); return true; case R.id.about_menu_item: Intent intenta = new Intent(this, AboutActivity.class); startActivity(intenta); return true; case R.id.tablecontents: return true; case R.id.page1: Intent intent1 = new Intent(this, ViewActivity.class); startActivity(intent1); return true; case R.id.page2: Intent intent2 = new Intent(this, page2.class); startActivity(intent2); return true; default: return super.onOptionsItemSelected(item); } } } </code></pre> <p>TouchImageView.java:</p> <pre><code> 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() { @Override 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); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload