From 8ef5f5aa357aac7d3be22604c95ebed1597c6d55 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Wed, 17 Oct 2012 13:18:40 +0400 Subject: revert webview --- src/org/fox/ttcomics/ComicFragment.java | 136 ++++++---------- src/org/fox/ttcomics/TouchImageView.java | 269 +++++++++++++++++++++++++++++++ 2 files changed, 314 insertions(+), 91 deletions(-) create mode 100644 src/org/fox/ttcomics/TouchImageView.java (limited to 'src') diff --git a/src/org/fox/ttcomics/ComicFragment.java b/src/org/fox/ttcomics/ComicFragment.java index aed247b..4acd732 100644 --- a/src/org/fox/ttcomics/ComicFragment.java +++ b/src/org/fox/ttcomics/ComicFragment.java @@ -1,29 +1,20 @@ package org.fox.ttcomics; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import android.annotation.SuppressLint; import android.app.Activity; import android.content.SharedPreferences; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.os.AsyncTask; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v4.app.Fragment; -import android.util.Base64; import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.webkit.WebSettings; -import android.webkit.WebSettings.ZoomDensity; -import android.webkit.WebView; import android.widget.ImageView; import android.widget.TextView; @@ -43,13 +34,39 @@ public class ComicFragment extends Fragment { m_page = page; } - @SuppressLint("NewApi") + public Bitmap loadImage(ComicArchive archive, int page) { + CommonActivity activity = (CommonActivity) getActivity(); + + try { + final BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeStream(archive.getItem(page), null, options); + + options.inSampleSize = CommonActivity.calculateInSampleSize(options, 512, 512); + options.inJustDecodeBounds = false; + + return BitmapFactory.decodeStream(archive.getItem(page), null, options); + } catch (OutOfMemoryError e) { + if (activity != null) { + activity.toast(R.string.error_out_of_memory); + } + e.printStackTrace(); + } catch (IOException e) { + if (activity != null) { + activity.toast(R.string.error_loading_image); + } + e.printStackTrace(); + } + + return null; + } + @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_comic, container, false); - final WebView web = (WebView) view.findViewById(R.id.comic); + TouchImageView image = (TouchImageView) view.findViewById(R.id.comic_image); if (savedInstanceState != null) { m_page = savedInstanceState.getInt("page"); @@ -59,85 +76,27 @@ public class ComicFragment extends Fragment { if (pager != null) { if (CommonActivity.isCompatMode() && m_prefs.getBoolean("use_dark_theme", false)) { - web.setBackgroundColor(0xff000000); + image.setBackgroundColor(0xff000000); } - WebSettings ws = web.getSettings(); - ws.setSupportZoom(true); - ws.setBuiltInZoomControls(false); // http://code.google.com/p/android/issues/detail?id=36713 - //ws.setCacheMode(WebSettings.LOAD_NO_CACHE); - //ws.setDefaultZoom(ZoomDensity.FAR); - ws.setUseWideViewPort(true); - ws.setLoadWithOverviewMode(true); - // prevent flicker in ics - if (android.os.Build.VERSION.SDK_INT >= 11) { - web.setLayerType(View.LAYER_TYPE_SOFTWARE, null); - } - - AsyncTask loadTask = new AsyncTask() { + image.setImageBitmap(loadImage(pager.getArchive(), m_page)); + image.setMaxZoom(4f); + image.setOnScaleChangedListener(new TouchImageView.OnScaleChangedListener() { @Override - protected ByteArrayOutputStream doInBackground(InputStream... params) { - try { - InputStream in = params[0]; - ByteArrayOutputStream out = new ByteArrayOutputStream(); - - int c; - while ((c = in.read()) != -1) { - out.write(c); - } - - out.flush(); - in.close(); - - return out; - - } catch (IOException e) { - e.printStackTrace(); - } catch (OutOfMemoryError e ) { - e.printStackTrace(); - } + public void onScaleChanged(float scale) { + ViewPager pager = (ViewPager) getActivity().findViewById(R.id.comics_pager); - return null; - } - - @Override - protected void onPostExecute(ByteArrayOutputStream result) { - if (getActivity() != null && isAdded()) { - if (result != null) { - String url = "data:image/jpeg;base64," + Base64.encodeToString(result.toByteArray(), Base64.DEFAULT | Base64.NO_WRAP); - - String content = "" + - "" + - "" + - "" + - "" + - "" + - "
" + - ""; - - web.loadDataWithBaseURL(null, content, "text/html", "utf-8", null); - } else { - ((CommonActivity) getActivity()).toast(R.string.error_loading_image); - } + if (pager != null) { + pager.setPagingEnabled(scale - 1.0f < 0.01); } } - - }; - - try { - loadTask.execute(pager.getArchive().getItem(m_page)); - } catch (IOException e) { - e.printStackTrace(); - } - - web.setOnTouchListener(new View.OnTouchListener() { + }); + + image.setCustomOnTouchListener(new View.OnTouchListener() { int m_x; int m_y; - + @Override public boolean onTouch(View view, MotionEvent event) { switch (event.getAction()) { @@ -164,12 +123,12 @@ public class ComicFragment extends Fragment { } }); - TextView page = (TextView) view.findViewById(R.id.comic_page); - - if (page != null) { - page.setText(String.valueOf(m_page+1)); - } + } + + TextView page = (TextView) view.findViewById(R.id.comic_page); + if (page != null) { + page.setText(String.valueOf(m_page+1)); } return view; @@ -183,11 +142,6 @@ public class ComicFragment extends Fragment { private void onRightSideTapped() { m_activity.selectNextComic(); } - - @Override - public void onPause() { - super.onPause(); - } @Override public void onAttach(Activity activity) { diff --git a/src/org/fox/ttcomics/TouchImageView.java b/src/org/fox/ttcomics/TouchImageView.java new file mode 100644 index 0000000..9a9efe6 --- /dev/null +++ b/src/org/fox/ttcomics/TouchImageView.java @@ -0,0 +1,269 @@ +/* + * TouchImageView.java + * By: Michael Ortiz + * Updated By: Patrick Lackemacher + * ------------------- + * Extends Android ImageView to include pinch zooming and panning. + */ + +package org.fox.ttcomics; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Matrix; +import android.graphics.PointF; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.ScaleGestureDetector; +import android.view.View; +import android.widget.ImageView; + +public class TouchImageView extends ImageView { + + public interface OnScaleChangedListener { + public void onScaleChanged(float scale); + } + + OnScaleChangedListener mScaleChangedListener; + View.OnTouchListener mCustomOnTouchListener; + + 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); + sharedConstructing(context); + } + + public TouchImageView(Context context, AttributeSet attrs) { + super(context, attrs); + sharedConstructing(context); + } + + private void sharedConstructing(Context 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 < width) { + deltaX = 0; + if (y + deltaY > 0) + deltaY = -y; + else if (y + deltaY < -bottom) + deltaY = -(y + bottom); + } else if (scaleHeight < height) { + deltaY = 0; + if (x + deltaX > 0) + deltaX = -x; + else if (x + deltaX < -right) + deltaX = -(x + right); + } else { + if (x + deltaX > 0) + deltaX = -x; + else if (x + deltaX < -right) + deltaX = -(x + right); + + if (y + deltaY > 0) + deltaY = -y; + else if (y + deltaY < -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 < CLICK && yDiff < CLICK) + performClick(); + break; + + case MotionEvent.ACTION_POINTER_UP: + mode = NONE; + break; + } + setImageMatrix(matrix); + invalidate(); + + if (mCustomOnTouchListener != null) { + mCustomOnTouchListener.onTouch(v, event); + } + + return true; // indicate event was handled + } + + }); + } + + @Override + public void setImageBitmap(Bitmap bm) { + super.setImageBitmap(bm); + if(bm != null) { + 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 = detector.getScaleFactor(); + float origScale = saveScale; + saveScale *= mScaleFactor; + if (saveScale > maxScale) { + saveScale = maxScale; + mScaleFactor = maxScale / origScale; + } else if (saveScale < minScale) { + saveScale = minScale; + mScaleFactor = minScale / origScale; + } + right = width * saveScale - width - (2 * redundantXSpace * saveScale); + bottom = height * saveScale - height - (2 * redundantYSpace * saveScale); + if (origWidth * saveScale <= width || origHeight * saveScale <= height) { + matrix.postScale(mScaleFactor, mScaleFactor, width / 2, height / 2); + if (mScaleFactor < 1) { + matrix.getValues(m); + float x = m[Matrix.MTRANS_X]; + float y = m[Matrix.MTRANS_Y]; + if (mScaleFactor < 1) { + if (Math.round(origWidth * saveScale) < width) { + if (y < -bottom) + matrix.postTranslate(0, -(y + bottom)); + else if (y > 0) + matrix.postTranslate(0, -y); + } else { + if (x < -right) + matrix.postTranslate(-(x + right), 0); + else if (x > 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 < 1) { + if (x < -right) + matrix.postTranslate(-(x + right), 0); + else if (x > 0) + matrix.postTranslate(-x, 0); + if (y < -bottom) + matrix.postTranslate(0, -(y + bottom)); + else if (y > 0) + matrix.postTranslate(0, -y); + } + } + + if (mScaleChangedListener != null) { + mScaleChangedListener.onScaleChanged(saveScale); + } + + 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); + } + + public void setOnScaleChangedListener(OnScaleChangedListener listener) { + mScaleChangedListener = listener; + } + + public void setCustomOnTouchListener(View.OnTouchListener listener) { + mCustomOnTouchListener = listener; + } +} -- cgit v1.2.3