zoukankan      html  css  js  c++  java
  • 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);
    }

    }

    装载类 一个layout

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

    Activity:

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

     
    配合Gallery的适配器类:

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

    }

     
    gallery中image的实现类:

    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 ->布局-> style -> color:

    <?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>

     
    转自:http://blog.csdn.net/maydie1989/article/details/6451033
     
     
     
     
      评论这张
    转发至微博
    转发至微博
    0  分享到:         
    阅读(9)| 评论(0)| 引用 (0) |举报
     

    历史上的今天

     

    相关文章

     

    最近读者

    登录后,您可以在此留下足迹。
     

    评论

    点击登录|昵称:
      取消
     
     
     
     
     
  • 相关阅读:
    微信卡券领用中的问题
    abp的开发20180425
    typescript 接口的新认识
    Jquery构建Form表单Post提交数据的简单方法
    EF使用时异常:对一个或多个实体的验证失败。有关详细信息
    VS快捷键简单记录
    比较和排序 IComparable And IComparer
    wpf全局异常
    MailBee的简单使用
    json数据的获取(网络摘抄)
  • 原文地址:https://www.cnblogs.com/zhwl/p/2405549.html
Copyright © 2011-2022 走看看