不知道大家有没有买小米,小米手机自带了一个图片查看器,他能对图片进行随意的浏览,扩大,缩小,以及翻页,使用效果感觉非常的不错
今天认着有时间,也就模仿他的功能写了一下,遇到不少的挫折,看不了不少的资料,希望今天的功夫没有白做,也希望对大家有帮助
在怎么说功能实现了,并结合自己现在所做的项目,进行了些许的改动,感觉更容易普及的使用,因为我们很多时候要从网上下载图片
然后对图片进行浏览什么的。
在做之前,说下思路:
目标: 实现 拖,拉,拽,扩大,缩小,以及翻屏
主要分两个大的方向:
1 拖,拉,拽,扩大,缩小 在本屏幕操作
2 翻屏是的额外的做,也并不是随意的就能翻屏,必须满足条件
但是当我们实现OnTouchListener 时候,他提供的只有 ACTION_DOWN
, ACTION_MOVE
,ACTION_UP 等操作
所以我们必须分情况,并且是三种情况:
第一种: none 可能用户什么也不做
第二种: DRAG 滑屏
第三种: ZOOM 扩大缩小
同时本程序考虑到有的android山寨手机可能还不支持多点触摸,所以同时加入了两个button ,不支持的多点触摸的也能对图片进行动态的扩大或者缩小
当然主要用的知识点就是Matrix 矩阵的一些常用方法,扩大,缩小,平移,偏移,剩下的都是一点皮毛的算法逻辑了,代码自己看啊
先上个图:
下面是代码:
/* * @project testbmplarge * @package com.bmp.large * @file testactivity.java * @version 1.0 * @author yourname * @time 2012-1-6 ����10:58:20 * CopyRight:������������Ϣ��������˾ 2012-1-6 */ package com.bmp.large; 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.util.DisplayMetrics; import android.util.FloatMath; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.GestureDetector.OnGestureListener; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast; public class testactivity extends Activity implements OnTouchListener,OnClickListener{ /* * * Class Descripton goes here. * * @class testactivity * @version 1.0 * @author yourname * @time 2012-1-6 ����10:58:20 */ private Button big,small; private Bitmap newbitmap; private GestureDetector mGestureDetector; Matrix matrix = new Matrix(); Matrix savedMatrix = new Matrix(); ImageView bmp; PointF first = new PointF(); PointF start = new PointF(); PointF mid = new PointF();; private float oldDist; static final int NONE = 0; static final int DRAG = 1; static final int ZOOM = 2; int mode = NONE; private long beginTime,endTime; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /*display.xml Layout */ setContentView(R.layout.main); big = (Button)this.findViewById(R.id.big); small = (Button)this.findViewById(R.id.small); big.setOnClickListener(this); small.setOnClickListener(this); //获取手机屏幕的宽和高 DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); int width = dm.widthPixels; int height = dm.heightPixels; // 获取图片本身的宽 和高 Bitmap mybitmap=BitmapFactory.decodeResource(getResources(), R.drawable.default_head); System.out.println("old==="+mybitmap.getWidth()); int widOrg=mybitmap.getWidth(); int heightOrg=mybitmap.getHeight(); // 宽 高 比列 float scaleWid = (float)width/widOrg; float scaleHeight = (float)height/heightOrg; float scale; bmp = (ImageView)this.findViewById(R.id.bmp); // 如果宽的 比列大于搞的比列 则用高的比列 否则用宽的 if(scaleWid>scaleHeight) { scale = scaleHeight; } else scale = scaleWid; // matrix=new Matrix(); bmp.setImageBitmap(mybitmap); matrix.postScale(scale,scale); bmp.setImageMatrix(matrix); bmp.setOnTouchListener(this); bmp.setLongClickable(true); savedMatrix.set(matrix); } @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub // mGestureDetector.onTouchEvent(event); System.out.println("action==="+event.getAction()); switch(event.getAction()& MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: beginTime = System.currentTimeMillis(); mode = DRAG; System.out.println("down"); first.set(event.getX(), event.getY()); start.set(event.getX(), event.getY()); break; case MotionEvent.ACTION_UP: endTime = System.currentTimeMillis(); System.out.println("endTime=="+(endTime - beginTime)); float x = event.getX(0) - first.x; float y = event.getY(0) - first.y; // 多长的距离 float move = FloatMath.sqrt(x * x + y * y); System.out.println("move=="+(move)); // 计算时间和移动的距离 来判断你想要的操作,经过测试90%情况能满足 if(endTime - beginTime<500&&move>20) { //这里就是做你上一页下一页的事情了。 Toast.makeText(this, "----do something-----", 1000).show(); } break; case MotionEvent.ACTION_MOVE: System.out.println("move"); if(mode == DRAG) { matrix.postTranslate(event.getX()-start.x, event.getY()-start.y); start.set(event.getX(), event.getY()); } else { float newDist = spacing(event); if (newDist > 10f) { // matrix.set(savedMatrix); float scale = newDist / oldDist; System.out.println("scale=="+scale); matrix.postScale(scale, scale, mid.x, mid.y); } oldDist = newDist; } break; case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); if (oldDist > 10f) { midPoint(mid, event); mode = ZOOM; } System.out.println("ACTION_POINTER_DOWN"); break; case MotionEvent.ACTION_POINTER_UP: System.out.println("ACTION_POINTER_UP"); break; } bmp.setImageMatrix(matrix); return false; } @Override public void onClick(View v) { // TODO Auto-generated method stub if(v==small) { matrix.postScale(0.5f,0.5f,0,0); // matrix.setScale(0.5f, 0.5f); bmp.setImageMatrix(matrix); } else { matrix.postScale(2f,2f); // matrix.setScale(2f,2f); bmp.setImageMatrix(matrix); } } /** * 计算拖动的距离 * @param event * @return */ private float spacing(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return FloatMath.sqrt(x * x + y * y); } /** * 计算两点的之间的中间点 * @param point * @param event */ private void midPoint(PointF point, MotionEvent event) { float x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); point.set(x / 2, y / 2); } }
本文章还存在不少的缺陷
后面一篇是对这一篇的延续和修改