android imageview 多点触碰(MultiTouch)实现图片拖拽移动缩放
刚用android手机 发现手机自带的图片浏览器挺酷 可以用手指移动 缩放 还有动画效果
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(recentFile), "image/*");
startActivity(intent);
就可以调用系统的图片浏览器查看手机上的图片了
于是想仿照着写一个
到网上看了不少资料 大概分为两种实现方式
http://download.csdn.net/source/3318880 ->源码
一种是利用Matrix的postTranslate和postScale方法分别进行移动和缩放
这种方式实质是对ImageView中的drawable进行缩放和移动
imageview组件本身并没有移动和缩放 这种方法实现起来比较简单 但是不知道如何获得经过移动后的drawable的坐标和大小 比较郁闷 因为调用imageview的各种方法拿到的都是其本身的大小和坐标
而另一种是直接对imageview进行操作,直接移动和改变组件本身的大小从而实现移动和缩放
核心类 继承->ImageView 并加入了一些动画效果
import android.content.Context;
import android.util.FloatMath;
import android.view.MotionEvent;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
/**
* 继承ImageView 实现了多点触碰的拖动和缩放
* @author Administrator
*
*/
publicclassTouchViewextendsImageView
{
staticfinalint NONE =0;
staticfinalint DRAG =1;//拖动中
staticfinalint ZOOM =2;//缩放中
staticfinalint BIGGER =3;//放大ing
staticfinalint SMALLER =4;//缩小ing
privateint mode = NONE;//当前的事件
privatefloat beforeLenght;//两触点距离
privatefloat afterLenght;//两触点距离
privatefloat scale =0.04f;//缩放的比例 X Y方向都是这个值 越大缩放的越快
privateint screenW;
privateint screenH;
/*处理拖动 变量 */
privateint start_x;
privateint start_y;
privateint stop_x ;
privateint stop_y ;
privateTranslateAnimation trans;//处理超出边界的动画
publicTouchView(Context context,int w,int h)
{
super(context);
this.setPadding(0,0,0,0);
screenW = w;
screenH = h;
}
/**
* 就算两点间的距离
*/
privatefloat spacing(MotionEventevent){
float x =event.getX(0)-event.getX(1);
float y =event.getY(0)-event.getY(1);
returnFloatMath.sqrt(x * x + y * y);
}
/**
* 处理触碰..
*/
@Override
publicboolean onTouchEvent(MotionEventevent)
{
switch(event.getAction()&MotionEvent.ACTION_MASK){
caseMotionEvent.ACTION_DOWN:
mode = DRAG;
stop_x =(int)event.getRawX();
stop_y =(int)event.getRawY();
start_x =(int)event.getX();
start_y = stop_y -this.getTop();
if(event.getPointerCount()==2)
beforeLenght = spacing(event);
break;
caseMotionEvent.ACTION_POINTER_DOWN:
if(spacing(event)>10f){
mode = ZOOM;
beforeLenght = spacing(event);
}
break;
caseMotionEvent.ACTION_UP:
/*判断是否超出范围 并处理*/
int disX =0;
int disY =0;
if(getHeight()<=screenH ||this.getTop()<0)
{
if(this.getTop()<0)
{
int dis = getTop();
this.layout(this.getLeft(),0,this.getRight(),0+this.getHeight());
disY = dis - getTop();
}
elseif(this.getBottom()>screenH)
{
disY = getHeight()- screenH+getTop();
this.layout(this.getLeft(), screenH-getHeight(),this.getRight(), screenH);
}
}
if(getWidth()<=screenW)
{
if(this.getLeft()<0)
{
disX = getLeft();
this.layout(0,this.getTop(),0+getWidth(),this.getBottom());
}
elseif(this.getRight()>screenW)
{
disX = getWidth()-screenW+getLeft();
this.layout(screenW-getWidth(),this.getTop(), screenW,this.getBottom());
}
}
if(disX!=0|| disY!=0)
{
trans =newTranslateAnimation(disX,0, disY,0);
trans.setDuration(500);
this.startAnimation(trans);
}
mode = NONE;
break;
caseMotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
caseMotionEvent.ACTION_MOVE:
/*处理拖动*/
if(mode == DRAG){
if(Math.abs(stop_x-start_x-getLeft())<88&&Math.abs(stop_y - start_y-getTop())<85)
{
this.setPosition(stop_x - start_x, stop_y - start_y, stop_x +this.getWidth()- start_x, stop_y - start_y +this.getHeight());
stop_x =(int)event.getRawX();
stop_y =(int)event.getRawY();
}
}
/*处理缩放*/
elseif(mode == ZOOM){
if(spacing(event)>10f)
{
afterLenght = spacing(event);
float gapLenght = afterLenght - beforeLenght;
if(gapLenght ==0){
break;
}
elseif(Math.abs(gapLenght)>5f)
{
if(gapLenght>0){
this.setScale(scale,BIGGER);
}else{
this.setScale(scale,SMALLER);
}
beforeLenght = afterLenght;
}
}
}
break;
}
returntrue;
}
/**
* 实现处理缩放
*/
privatevoid setScale(float temp,int flag){
if(flag==BIGGER){
this.setFrame(this.getLeft()-(int)(temp*this.getWidth()),
this.getTop()-(int)(temp*this.getHeight()),
this.getRight()+(int)(temp*this.getWidth()),
this.getBottom()+(int)(temp*this.getHeight()));
}elseif(flag==SMALLER){
this.setFrame(this.getLeft()+(int)(temp*this.getWidth()),
this.getTop()+(int)(temp*this.getHeight()),
this.getRight()-(int)(temp*this.getWidth()),
this.getBottom()-(int)(temp*this.getHeight()));
}
}
/**
* 实现处理拖动
*/
privatevoid setPosition(int left,int top,int right,int bottom){
this.layout(left,top,right,bottom);
}
}
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.widget.AbsoluteLayout;
import android.widget.ImageView.ScaleType;
/**
* 一个绝对布局
* @author Administrator
*
*/
@SuppressWarnings("deprecation")
publicclassViewScrollextendsAbsoluteLayout
{
privateint screenW;//可用的屏幕宽
privateint screenH;//可用的屏幕高 总高度-上面组件的总高度
privateint imgW;//图片原始宽
privateint imgH;//图片原始高
privateTouchView tv;
publicViewScroll(Context context,int resId,View topView)
{
super(context);
screenW =((Activity)context).getWindowManager().getDefaultDisplay().getWidth();
screenH =((Activity)context).getWindowManager().getDefaultDisplay().getHeight()-(topView==null?190:topView.getBottom()+50);
tv =newTouchView(context,screenW,screenH);
tv.setImageResource(resId);
Bitmap img =BitmapFactory.decodeResource(context.getResources(), resId);
imgW = img.getWidth();
imgH = img.getHeight();
int layout_w = imgW>screenW?screenW:imgW;//实际显示的宽
int layout_h = imgH>screenH?screenH:imgH;//实际显示的高
if(layout_w==screenW||layout_h==screenH)
tv.setScaleType(ScaleType.FIT_XY);
tv.setLayoutParams(newAbsoluteLayout.LayoutParams(layout_w,layout_h , layout_w==screenW?0:(screenW-layout_w)/2, layout_h==screenH?0:(screenH-layout_h)/2));
this.addView(tv);
}
}
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Gallery;
import android.widget.LinearLayout;
import android.widget.AdapterView.OnItemClickListener;
/**
* activity
* @author Administrator
*
*/
publicclassGalleryMainextendsActivityimplementsOnItemClickListener
{
privateViewScroll detail;
privateImageAdapter ia;
privateLinearLayout ll;
privateLinearLayout.LayoutParams parm;
privateGallery g;
@Override
protectedvoid onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
g =(Gallery) findViewById(R.id.myggg);
ll =(LinearLayout) findViewById(R.id.twill);
parm =newLinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,LinearLayout.LayoutParams.FILL_PARENT);
ia =newImageAdapter(this);
detail =newViewScroll(GalleryMain.this, ia.imgIds[0],g);
ll.addView(detail,parm);
g.setAdapter(ia);
g.setOnItemClickListener(this);
}
@Override
publicvoid onItemClick(AdapterView<?> arg0,View arg1,int arg2,long arg3)
{
ll.removeView(detail);
detail =newViewScroll(GalleryMain.this, ia.imgIds[arg2],g);
ll.addView(detail,parm);
}
}
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
/**
* Gallery的适配器类
* @author Administrator
*
*/
publicclassImageAdapterextendsBaseAdapter
{
/*图片素材*/
publicint[] imgIds ={R.drawable.jpg,R.drawable.pic};
privateContext context;
publicImageAdapter(Context context)
{
this.context = context;
}
@Override
publicint getCount()
{
return imgIds.length;
}
@Override
publicObject getItem(int position)
{
returnnull;
}
@Override
publiclong getItemId(int position)
{
return0;
}
@Override
publicView getView(int position,View convertView,ViewGroup parent)
{
ImageView img =newImageViewImp(context);
img.setImageResource(imgIds[position]);
img.setScaleType(ScaleType.CENTER);
img.setLayoutParams(newGallery.LayoutParams(155,150));
return img;
}
}
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.view.MotionEvent;
import android.widget.ImageView;
/**
* ImageAdapter中ImageView的实现类
* @author Administrator
*
*/
publicclassImageViewImpextendsImageView
{
privateint alpha =250;
privateboolean pressed =false;
publicImageViewImp(Context context)
{
super(context);
}
Matrix m;
publicvoid show()
{
newThread(){
publicvoid run(){
int time =2000;
try
{
pressed =true;
while(time>0)
{
Thread.sleep(200);
time -=200;
alpha-=25;
postInvalidate();
}
pressed =false;
}
catch(Exception e)
{
e.printStackTrace();
}
};
}.start();
}
@Override
publicboolean onTouchEvent(MotionEventevent)
{
if(event.getAction()==MotionEvent.ACTION_DOWN)
show();
returnfalse;
}
@Override
protectedvoid onDraw(Canvas canvas)
{
Paint p =newPaint();
p.setColor(Color.WHITE);
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(10);
BitmapDrawable bd =(BitmapDrawable) getDrawable();
if(bd!=null)
{
canvas.drawBitmap(imageScale(bd.getBitmap(),107,113),21,18, p);
}
canvas.drawBitmap(BitmapFactory.decodeResource(getContext().getResources(), R.drawable.kua),0,0, p);
if(isPressed())
{
canvas.drawRect(5,5,140,140,p);
}
if(pressed)
{
p.setAlpha(alpha);
canvas.drawRect(5,5,140,140,p);
}
}
publicstaticBitmap imageScale(Bitmap bitmap,int dst_w,int dst_h){
int src_w = bitmap.getWidth();
int src_h = bitmap.getHeight();
float scale_w =((float)dst_w)/src_w;
float scale_h =((float)dst_h)/src_h;
Matrix matrix =newMatrix();
matrix.postScale(scale_w, scale_h);
Bitmap dstbmp =Bitmap.createBitmap(bitmap,0,0, src_w, src_h, matrix,true);
return dstbmp;
}
}
<?xml version="1.0" encoding="utf-8"?>
<!--main.xml 在layout下-->
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_height="fill_parent"
android:layout_width="fill_parent"android:gravity="top"android:id="@+id/twill"
android:background="@android:color/transparent">
<Gallery
android:id="@+id/myggg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<!--style.xml 在values下-->
<resources>
<stylename="testStyle">
<itemname="android:textColor">#EC9237</item>
</style>
<stylename="transparent">
<itemname="android:windowBackground">@drawable/translucent_background</item>
<itemname="android:windowIsTranslucent">true</item>
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<!--color.xml 在values下-->
<resources>
<drawablename="c1">#FFFFFFFF</drawable>
<drawablename="c2">#00FFFF</drawable>
<drawablename="translucent_background">#7F000000</drawable>
</resources>
评论