这些天都在搞图片处理,要求显示大图(2m以上)都知道安卓应用默认加载的图片大小是不能太大的,如果太大的话就会内存溢出。而且不能压缩失真,其实android自带的一些控件是能实现拖拽的但都不符合我的需求,于是在网上找答案,还是有点眉目的就是没有和我一模一样的需求,于是那过来比对修改搞来了半天,终于还是出来效果了。还是相信那么一句话,没有白费的功夫。有付出还是会有回报的。现在为了和我一样需求的人不至于乱费时间,我把源码贴出来共享一下。
package com.hcq.jpg;
import java.io.InputStream;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewConfiguration;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
@SuppressLint("NewApi")
public class Main extends Activity {
ImageView iv;
float lastX ,lastY;
int globalX, globalY;
int globalWidth, globalHeight;
final Handler handler = new Handler();
Bitmap png = null;
float mTouchSlop;
private ZoomImageView zoomImageView;
private boolean mIsDragging;
Runnable mSetBitmap = new Runnable() {
@Override
public void run() {
// setImage();
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
final Window win = getWindow();
win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
iv = new ImageView(this);
iv.setAdjustViewBounds(true);
iv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
iv.setScaleType(ScaleType.CENTER);
width = iv.getWidth();
height = iv.getHeight();
//setContentView(iv);
iv.setOnTouchListener(new MulitPointTouchListener());
zoomImageView = (ZoomImageView) findViewById(R.id.zoom_image_view);
// 取出图片路径,并解析成Bitmap对象,然后在ZoomImageView中显示
//String imagePath = getIntent().getStringExtra("image_path");
InputStream is = getResources().openRawResource(R.drawable.ta);
png = BitmapFactory.decodeStream(is);
//bitmap = BitmapFactory.decodeFile(imagePath);
zoomImageView.setImageBitmap(png);
new Thread(){
@Override
public void run() {
super.run();
try {
InputStream is = getResources().openRawResource(R.drawable.one);
png = BitmapFactory.decodeStream(is);
handler.post(mSetBitmap);
} catch (Exception e) {
e.printStackTrace();
}
}}.start();
final ViewConfiguration configuration = ViewConfiguration.get(getApplicationContext());
mTouchSlop = configuration.getScaledTouchSlop();
}
void setImage() {
if(png != null) {
iv.setImageBitmap(png);
globalWidth = png.getWidth();
globalHeight = png.getHeight();
handler.removeCallbacks(mSetBitmap);
iv.setScaleType(ScaleType.MATRIX);
iv.setImageMatrix(iv.getImageMatrix());
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public class MulitPointTouchListener implements OnTouchListener {
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
PointF pf = new PointF();
float mx, my;
public MulitPointTouchListener() {
super();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
float dx = event.getX() - lastX,dy = event.getX() - lastY;
switch(event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
matrix.set(view.getImageMatrix());
savedMatrix.set(matrix);
pf.set(event.getX(), event.getY());
mIsDragging =false;
break;
case MotionEvent.ACTION_MOVE:
matrix.set(savedMatrix);
// mx = event.getX() - pf.x;
// my = event.getY() - pf.y;
// globalX += mx;
// globalY += my;
// lastX = event.getX();
// lastY = event.getY();
// matrix.postTranslate(mx, my);
// Log.i("MXY", pf.x + "," + pf.y + "," + mx + "," + my + "," + view.getWidth() + "," + view.getHeight());
// 只有单指按在屏幕上移动时,为拖动状态
float xMove = event.getX();
float yMove = event.getY();
if (lastXMove == -1 && lastYMove == -1) {
lastXMove = xMove;
lastYMove = yMove;
}
movedDistanceX = xMove - lastXMove;
movedDistanceY = yMove - lastYMove;
// 进行边界检查,不允许将图片拖出边界
if (totalTranslateX + movedDistanceX > 0) {
movedDistanceX = 0;
} else if (width - (totalTranslateX + movedDistanceX) > globalWidth) {
movedDistanceX = 0;
}
if (totalTranslateY + movedDistanceY > 0) {
movedDistanceY = 0;
} else if (height - (totalTranslateY + movedDistanceY) > globalHeight) {
movedDistanceY = 0;
}
// 调用onDraw()方法绘制图片
lastXMove = xMove;
lastYMove = yMove;
matrix.postTranslate(movedDistanceX, movedDistanceY);
view.setImageMatrix(matrix);
break;
default:
break;
}
return true;
}
}
/**
* 记录当前图片的宽度,图片被缩放时,这个值会一起变动
*/
private float currentBitmapWidth;
/**
* 记录当前图片的高度,图片被缩放时,这个值会一起变动
*/
private float currentBitmapHeight;
/**
* ZoomImageView控件的宽度
*/
private int width;
/**
* ZoomImageView控件的高度
*/
private int height;
/**
* 记录上次手指移动时的横坐标
*/
private float lastXMove = -1;
/**
* 记录上次手指移动时的纵坐标
*/
private float lastYMove = -1;
/**
* 记录手指在横坐标方向上的移动距离
*/
private float movedDistanceX;
/**
* 记录手指在纵坐标方向上的移动距离
*/
private float movedDistanceY;
/**
* 记录图片在矩阵上的横向偏移值
*/
private float totalTranslateX;
/**
* 记录图片在矩阵上的纵向偏移值
*/
private float totalTranslateY ;
@Override
protected void onStop() {
if (png != null) {
if (!png.isRecycled()) {
png.recycle();
png = null;
System.gc();
}
}
super.onStop();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (png != null) {
if (!png.isRecycled()) {
png.recycle();
png = null;
System.gc();
}
}
}
}