高仿新浪点击图片放大(可以拖动,动态缩小放大,以及再次点击图片消失和保存图片的功能)

有图有真相:

最近在做项目的时候用到了点击图片放大效果,于是就开始实现,本以为挺简单的,实现起来还是遇到不少的小问题啊:

第一:只实现点击图片放大,再次点击消失,这个好实现;

第二:只实现图片可以拖动,而且可以动态缩小放大,这个也好实现;

第三:第一 和第二同步实现就出现问题了:

具体的问题是:

(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);
	}

}

大家若是有更好的实现方法,请给留个链接,大家互相学习一下!

时间: 2024-12-25 18:46:57

高仿新浪点击图片放大(可以拖动,动态缩小放大,以及再次点击图片消失和保存图片的功能)的相关文章

仿新浪首页、主题、详情页,纯html静态页面

仿新浪首页.主题.详情页,纯html静态页面,下载地址: http://download.csdn.net/detail/sweetsuzyhyf/8085535

android listview的HeadView左右切换图片(仿新浪,网易,百度等切换图片)

首先我们还是看一些示例:(网易,新浪,百度) 显示效果都不错,可是手感就不一样了,百度最棒,网易还行,新浪就操作很不好,这里我说的是滑动切换图片.自己可以测试一下.不得不说牛叉的公司确实有哦牛叉的道理. 下面我简单的介绍下实现方法:其实就是listview addHeaderView.只不过这个view是一个可以切换图片的view,至于这个view怎么做,就要根据自己的喜爱了,实现有多种方法,下面我简单介绍一下. 第一种:ViewFlipper+GestureDetector 主布局就是一个li

【转】Android android listview的HeadView左右切换图片(仿新浪,网易,百度等切换图片)

首先我们还是看一些示例:(网易,新浪,百度)      下面我简单的介绍下实现方法:其实就是listview addHeaderView.只不过这个view是一个可以切换图片的view,至于这个view怎么做,就要根据自己的喜爱了,实现有多种方法,下面我简单介绍一下. 第一种:ViewFlipper+GestureDetector 主布局就是一个listview,这里就不介绍了,我介绍下切换图片布局head_iamge.xml 1 <span style="font-size:12px;&

Android仿新浪新闻SlidingMenu界面的实现 .

先看看原图: 如图所示,这种侧滑效果以另一种方式替代了原先tab导航的那种用户体验方式 给人耳目一新的感觉,现已被广大知名应用所效仿,如新浪新闻,网易新闻,人人网等 那么这种效果该如何实现呢?那就需要用到一个开源库SlidingMenu Github地址:https://github.com/jfeinstein10/SlidingMenu 里面包含了demo示例,相关效果图如下: 同时该库又依赖另一个开源库ActionBarSherkLock ,有关该库的介绍,请看此博文http://blog

安卓开发笔记——高仿新浪微博文字处理(实现关键字高亮,自定义表情替换并加入点击事件实现)

先让大家看下效果图,这个是我自己在闲暇时间仿写的新浪微博客户端: 今天来讲讲如何实现上图的效果,这里需要用到SpannableString这个工具类,如果你对这个类并不熟悉,可以先看下我之前写的2篇文章: <安卓开发笔记——个性化TextView(新浪微博)>:http://www.cnblogs.com/lichenwei/p/4411607.html <安卓开发笔记——丰富多彩的TextView>:http://www.cnblogs.com/lichenwei/p/46120

仿新浪部分静态页面展示

1 <!DOCTYPE html> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> 5 <title></title> 6 <link href="css/d

仿新浪下拉菜单

要求 仿新浪网,鼠标移入显示下拉菜单,鼠标移出隐藏下拉菜单,具体表现如下图: 代码 <ul> <li id="top">微博</li> <li class="hide">私信</li> <li class="hide">评论</li> <li class="hide">@我</li> </ul> <sc

高仿新浪微博,写了个小demo

运用新浪开发的微博数据接口,花了两天时间高仿新浪iphone手机客户端的写了新特性和首页,感觉运用到的知识点还是挺多的,尤其实在框架的搭建和代码的封装上,直接决定了系统的重用性和扩展性,案例视图:                            共享几个案例中用到的小技巧: (1) 重写按钮的样式    一般按钮中的文字和图片都是左右排, 那么如何按照自己的想法,任意的控制按钮中元素的排列呢? 1 #import "XHcenterBtn.h" 2 #import "U

新浪新闻客户端源码

高仿新浪新闻客户端,实现了大部分功能以及界面部分,自动获取新闻信息数据.定位当前位置获取气象信息数据并展示,有兴趣的可以看看. 下载地址:http://www.devstore.cn/code/info/1014.html 运行截图: