有图有真相:
最近在做项目的时候用到了点击图片放大效果,于是就开始实现,本以为挺简单的,实现起来还是遇到不少的小问题啊:
第一:只实现点击图片放大,再次点击消失,这个好实现;
第二:只实现图片可以拖动,而且可以动态缩小放大,这个也好实现;
第三:第一 和第二同步实现就出现问题了:
具体的问题是:
(1)setOnClickListener 和 setOnTouchListener 同时设置的时候,若是setOnTouchListener的返回值为true,则不会再执行setOnClickListener ;若是返回为false,则会执行setOnClickListener
(2)将setOnTouchListener的返回值设为false之后,运行项目,图片缩小放大之后会直接消失,也就是直接执行了setOnClickListener ,但是项目的要求是,图片移动了或者放大缩小了,依旧显示图片,只有点击的时候才会使图片消失,我于是就用一个变量进行控制手指点击屏幕之后的大小小于1的时候才算是点击了图片,从而让图片消失,具体不多说了,看图和代码:
public class ImageToFullScreenActivity extends Activity implements
OnClickListener {
private String mImageUrl;
private ImageWorker mImageWorker;
private int mImageWidth;
private int mImageHeight;
private ImageView mFullImageView;
private LinearLayout mImageLayout;
private ImageView mSaveImage;
private Boolean isShutDownPic = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image_to_full_screen);
mImageUrl = getIntent().getStringExtra("imageUrl");
init();
}
private void init() {
mImageLayout = (LinearLayout) findViewById(R.id.image_layout);
mFullImageView = (ImageView) findViewById(R.id.full_image);
mSaveImage = (ImageView) findViewById(R.id.save_image);
mSaveImage.setOnClickListener(this);
mImageLayout.setOnClickListener(this);
mFullImageView.setOnClickListener(this);
mFullImageView.setOnTouchListener(new TouchListener());
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
mImageWidth = (int) (outMetrics.widthPixels * 1.0d);
mImageHeight = mImageWidth;
ImageCacheParams cacheParams = new ImageCacheParams();
cacheParams.loadingResId = R.drawable.image_full_screen;
cacheParams.memCacheSize = ImageCache.DEFAULT_MEM_CACHE_SIZE_BIG;
cacheParams.reqWidth = mImageWidth;
cacheParams.reqHeight = mImageHeight;
mImageWorker = new ImageWorker(this,
(HealthApplication) getApplication());
mImageWorker.addParams(cacheParams);
mImageWorker.loadBitmap(mImageUrl, mFullImageView);
LayoutParams params = new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
mFullImageView.setLayoutParams(params);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.save_image:
SaveImageToSysAlbum();
break;
case R.id.image_layout:
if(isShutDownPic){
ImageToFullScreenActivity.this.finish();
}
isShutDownPic = true;
break;
case R.id.full_image:
if(isShutDownPic){
ImageToFullScreenActivity.this.finish();
}
isShutDownPic = true;
break;
default:
break;
}
}
/**
* 將ImageView中的圖片保存到系统相册
*/
private void SaveImageToSysAlbum() {
if (FileUtil.isSdCardExist()) {
BitmapDrawable bmpDrawable = (BitmapDrawable) mFullImageView
.getDrawable();
Bitmap bmp = bmpDrawable.getBitmap();
if (bmp != null) {
try {
/*
* ContentResolver cr = getContentResolver(); String url =
* MediaStore.Images.Media.insertImage(cr, bmp,
* String.valueOf(System.currentTimeMillis()), "");
*/
File tempFile = new File(Environment
.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM).getPath()
+ "/"
+ String.valueOf(System.currentTimeMillis())
+ ".png");
if (tempFile.exists()) {
tempFile.delete();
}
try {
tempFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream fOut = null;
try {
fOut = new FileOutputStream(tempFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
bmp.compress(Bitmap.CompressFormat.PNG, 100, fOut);
try {
fOut.flush();
fOut.close();
} catch (IOException e) {
// TODO: handle exception
e.printStackTrace();
}
Toast.makeText(this, getString(R.string.save_succ),
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(this, getString(R.string.no_iamge_save_fail),
Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, getString(R.string.no_sdcard_save_fail),
Toast.LENGTH_SHORT).show();
}
String release = android.os.Build.VERSION.RELEASE;
String tempID = release.substring(0, 3);
if (Double.parseDouble(tempID) >= 4.4) {// 安卓4.4以上版本的时候使用这个,以下的使用else语句里面的
MediaScannerConnection.scanFile(
this,
new String[] { Environment
.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM).getPath()
+ "/" }, null, null);
} else {
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
MediaScannerConnection.scanFile(
this,
new String[] { Environment
.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM).getPath()
+ "/" }, null, null);
}
}
private class TouchListener implements OnTouchListener {
private PointF startPoint = new PointF();
private Matrix matrix = new Matrix();
private Matrix currentMaritx = new Matrix();
private int mode = 0; // 用于标记模式
private static final int DRAG = 1; // 拖动
private static final int ZOOM = 2; // 放大
private float startDis = 0;
private PointF midPoint; // 中心点
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mode = DRAG; // 拖拽
currentMaritx.set(mFullImageView.getImageMatrix()); // 记录ImageView当前移动位置
startPoint.set(event.getX(), event.getY()); // 开始点
break;
case MotionEvent.ACTION_MOVE:// 移动事件
float tempX = event.getX() - startPoint.x;
float tempY = event.getY() - startPoint.y;
/**
* 控制移动小于1.0的情况下,视为没有移动,执行点击事件
*/
if(Math.abs(tempX) < 1.0 && Math.abs(tempY) < 1.0){
isShutDownPic = true;
}else {
isShutDownPic = false;
}
mFullImageView.setScaleType(ImageView.ScaleType.MATRIX);
if (mode == DRAG) { // 图片拖动事件
float dx = event.getX() - startPoint.x; // x轴移动距离
float dy = event.getY() - startPoint.y;
matrix.set(currentMaritx); // 在当前的位置基础上移动
matrix.postTranslate(dx, dy);
} else if (mode == ZOOM) { // 图片放大事件
float endDis = distance(event); // 结束距离
if (endDis > 10f) {
float scale = endDis / startDis; // 放大倍数
matrix.set(currentMaritx);
matrix.postScale(scale, scale, midPoint.x, midPoint.y);
}
}
break;
case MotionEvent.ACTION_UP:
mode = 0;
break;
// 有手指离开屏幕,但屏幕还有触点(手指)
case MotionEvent.ACTION_POINTER_UP:
mode = 0;
break;
// 当屏幕上已经有触点(手指),再有一个手指压下屏幕
case MotionEvent.ACTION_POINTER_DOWN:
mode = ZOOM;
startDis = distance(event);
if (startDis > 10f) { // 避免手指上有两个
midPoint = mid(event);
currentMaritx.set(mFullImageView.getImageMatrix()); // 记录当前的缩放倍数
}
break;
}
// 显示缩放后的图片
mFullImageView.setImageMatrix(matrix);
return false;
}
}
/**
* 计算两点之间的距离
*
* @param event
* @return
*/
public static float distance(MotionEvent event) {
float dx = event.getX(1) - event.getX(0);
float dy = event.getY(1) - event.getY(0);
return FloatMath.sqrt(dx * dx + dy * dy);
}
/**
* 计算两点之间的中间点
*
* @param event
* @return
*/
public static PointF mid(MotionEvent event) {
float midX = (event.getX(1) + event.getX(0)) / 2;
float midY = (event.getY(1) + event.getY(0)) / 2;
return new PointF(midX, midY);
}
}