欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android编程实现图片的浏览、缩放、拖动和自动居中效果

程序员文章站 2023-12-02 17:57:34
本文实例讲述了android编程实现图片的浏览、缩放、拖动和自动居中效果的方法。分享给大家供大家参考,具体如下: touch.java /** * 图片浏览...

本文实例讲述了android编程实现图片的浏览、缩放、拖动和自动居中效果的方法。分享给大家供大家参考,具体如下:

touch.java

/**
 * 图片浏览、缩放、拖动、自动居中
 */
public class touch extends activity implements ontouchlistener {
 matrix matrix = new matrix();
 matrix savedmatrix = new matrix();
 displaymetrics dm;
 imageview imgview;
 bitmap bitmap;
 float minscaler;// 最小缩放比例
 static final float max_scale = 4f;// 最大缩放比例
 static final int none = 0;// 初始状态
 static final int drag = 1;// 拖动
 static final int zoom = 2;// 缩放
 int mode = none;
 pointf prev = new pointf();
 pointf mid = new pointf();
 float dist = 1f;
 @override
 public void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.scale);
  imgview = (imageview) findviewbyid(r.id.imag);// 获取控件
  bitmap = bitmapfactory.decoderesource(getresources(), this.getintent()
    .getextras().getint("img"));// 获取图片资源
  imgview.setimagebitmap(bitmap);// 填充控件
  imgview.setontouchlistener(this);// 设置触屏监听
  dm = new displaymetrics();
  getwindowmanager().getdefaultdisplay().getmetrics(dm);// 获取分辨率
  minzoom();
  center();
  imgview.setimagematrix(matrix);
 }
 /**
  * 触屏监听
  */
 public boolean ontouch(view v, motionevent event) {
  switch (event.getaction() & motionevent.action_mask) {
  // 主点按下
  case motionevent.action_down:
   savedmatrix.set(matrix);
   prev.set(event.getx(), event.gety());
   mode = drag;
   break;
  // 副点按下
  case motionevent.action_pointer_down:
   dist = spacing(event);
   // 如果连续两点距离大于10,则判定为多点模式
   if (spacing(event) > 10f) {
    savedmatrix.set(matrix);
    midpoint(mid, event);
    mode = zoom;
   }
   break;
  case motionevent.action_up:
  case motionevent.action_pointer_up:
   mode = none;
   break;
  case motionevent.action_move:
   if (mode == drag) {
    matrix.set(savedmatrix);
    matrix.posttranslate(event.getx() - prev.x, event.gety()
      - prev.y);
   } else if (mode == zoom) {
    float newdist = spacing(event);
    if (newdist > 10f) {
     matrix.set(savedmatrix);
     float tscale = newdist / dist;
     matrix.postscale(tscale, tscale, mid.x, mid.y);
    }
   }
   break;
  }
  imgview.setimagematrix(matrix);
  checkview();
  return true;
 }
 /**
  * 限制最大最小缩放比例,自动居中
  */
 private void checkview() {
  float p[] = new float[9];
  matrix.getvalues(p);
  if (mode == zoom) {
   if (p[0] < minscaler) {
    matrix.setscale(minscaler, minscaler);
   }
   if (p[0] > max_scale) {
    matrix.set(savedmatrix);
   }
  }
  center();
 }
 /**
  * 最小缩放比例,最大为100%
  */
 private void minzoom() {
  minscaler = math.min(
    (float) dm.widthpixels / (float) bitmap.getwidth(),
    (float) dm.heightpixels / (float) bitmap.getheight());
  if (minscaler < 1.0) {
   matrix.postscale(minscaler, minscaler);
  }
 }
 private void center() {
  center(true, true);
 }
 /**
  * 横向、纵向居中
  */
 protected void center(boolean horizontal, boolean vertical) {
  matrix m = new matrix();
  m.set(matrix);
  rectf rect = new rectf(0, 0, bitmap.getwidth(), bitmap.getheight());
  m.maprect(rect);
  float height = rect.height();
  float width = rect.width();
  float deltax = 0, deltay = 0;
  if (vertical) {
   // 图片小于屏幕大小,则居中显示。大于屏幕,上方留空则往上移,下方留空则往下移
   int screenheight = dm.heightpixels;
   if (height < screenheight) {
    deltay = (screenheight - height) / 2 - rect.top;
   } else if (rect.top > 0) {
    deltay = -rect.top;
   } else if (rect.bottom < screenheight) {
    deltay = imgview.getheight() - rect.bottom;
   }
  }
  if (horizontal) {
   int screenwidth = dm.widthpixels;
   if (width < screenwidth) {
    deltax = (screenwidth - width) / 2 - rect.left;
   } else if (rect.left > 0) {
    deltax = -rect.left;
   } else if (rect.right < screenwidth) {
    deltax = screenwidth - rect.right;
   }
  }
  matrix.posttranslate(deltax, deltay);
 }
 /**
  * 两点的距离
  */
 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);
 }
 /**
  * 两点的中点
  */
 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);
 }
}

scale.xml

<?xml version="1.0" encoding="utf-8"?>
<framelayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:layout_gravity="center" >
 <imageview
  android:id="@+id/imag"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:layout_gravity="center"
  android:scaletype="matrix" >
 </imageview>
</framelayout>

希望本文所述对大家android程序设计有所帮助。