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

Android实现手势控制ImageView图片大小

程序员文章站 2024-02-19 22:50:49
本文实例实现的主要功能是在imageview中识别手势用以控制图片放大或缩小,具有一定的参考价值,分享给大家。 public class matriximagev...

本文实例实现的主要功能是在imageview中识别手势用以控制图片放大或缩小,具有一定的参考价值,分享给大家。

public class matriximageview extends imageview {
  private gesturedetector mgesturedetector;
  private matrix mmatrix = new matrix();
  private float mimagewidth;
  private float mimageheight;
  private float mscale;
  private onmovinglistener mmovelistener;
  private onsingletaplistener msingletaplistener;
  public matriximageview(context context, attributeset attrs) {
    super(context, attrs);
    init();
  }
  public matriximageview(context context) {
    super(context, null);
    init();
  }
  private void init() {
    matrixtouchlistener listener = new matrixtouchlistener();
    setontouchlistener(listener);
    mgesturedetector = new gesturedetector(getcontext(),
        new gesturelistener(listener));
    setbackgroundcolor(color.black);
    setscaletype(scaletype.fit_center);
  }
  public void setonmovinglistener(onmovinglistener listener) {
    mmovelistener = listener;
  }
  public void setonsingletaplistener(onsingletaplistener onsingletaplistener) {
    this.msingletaplistener = onsingletaplistener;
  }
  @override
  public void setimagebitmap(bitmap bm) {
    super.setimagebitmap(bm);
    if (getwidth() == 0) {

      viewtreeobserver vto = getviewtreeobserver();
      vto.addonpredrawlistener(new viewtreeobserver.onpredrawlistener() {
        public boolean onpredraw() {

          initdata();
          matriximageview.this.getviewtreeobserver()
              .removeonpredrawlistener(this);
          return true;
        }

      });
    } else {
      initdata();
    }
  }
  private void initdata() {
    mmatrix.set(getimagematrix());
    float[] values = new float[9];
    mmatrix.getvalues(values);
    mimagewidth = getwidth() / values[matrix.mscale_x];
    mimageheight = (getheight() - values[matrix.mtrans_y] * 2)
        / values[matrix.mscale_y];
    mscale = values[matrix.mscale_x];
  }
  public class matrixtouchlistener implements ontouchlistener {
    private static final int mode_drag = 1;
    private static final int mode_zoom = 2;
    private static final int mode_unable = 3;
    private static final float max_scale = 6;
    private static final float double_click_sacle = 2;
    private int mmode = 0;
    private float mstartdis;
    private matrix mcurrentmatrix = new matrix();
    private boolean mleftdragable;
    private boolean mrightdragable;
    private boolean mfirstmove = false;
    private pointf mstartpoint = new pointf();
    @override
    public boolean ontouch(view v, motionevent event) {
      switch (event.getactionmasked()) {
      case motionevent.action_down:
        mmode = mode_drag;
        mstartpoint.set(event.getx(), event.gety());
        ismatrixenable();
        startdrag();
        checkdragable();
        break;
      case motionevent.action_up:
      case motionevent.action_cancel:
        resetmatrix();
        stopdrag();
        break;
      case motionevent.action_move:
        if (mmode == mode_zoom) {
          setzoommatrix(event);
        } else if (mmode == mode_drag) {
          setdragmatrix(event);
        } else {
          stopdrag();
        }
        break;
      case motionevent.action_pointer_down:
        if (mmode == mode_unable)
          return true;
        mmode = mode_zoom;
        mstartdis = distance(event);
        break;
      case motionevent.action_pointer_up:
        break;
      default:
        break;
      }

      return mgesturedetector.ontouchevent(event);

    }

    private void startdrag() {

      if (mmovelistener != null)

        mmovelistener.startdrag();

    }

    private void stopdrag() {

      if (mmovelistener != null)

        mmovelistener.stopdrag();

    }

    private void checkdragable() {

      mleftdragable = true;

      mrightdragable = true;

      mfirstmove = true;

      float[] values = new float[9];

      getimagematrix().getvalues(values);

      if (values[matrix.mtrans_x] >= 0)

        mrightdragable = false;

      if ((mimagewidth) * values[matrix.mscale_x]

          + values[matrix.mtrans_x] <= getwidth()) {

        mleftdragable = false;

      }

    }

    public void setdragmatrix(motionevent event) {

      if (iszoomchanged()) {

        float dx = event.getx() - mstartpoint.x;

        float dy = event.gety() - mstartpoint.y;

        if (math.sqrt(dx * dx + dy * dy) > 10f) {

          mstartpoint.set(event.getx(), event.gety());

          mcurrentmatrix.set(getimagematrix());

          float[] values = new float[9];

          mcurrentmatrix.getvalues(values);

          dy = checkdybound(values, dy);

          dx = checkdxbound(values, dx, dy);

          mcurrentmatrix.posttranslate(dx, dy);

          setimagematrix(mcurrentmatrix);

        }
      } else {
        stopdrag();
      }
    }
    private boolean iszoomchanged() {
      float[] values = new float[9];
      getimagematrix().getvalues(values);
      float scale = values[matrix.mscale_x];
      return scale != mscale;
    }
    private float checkdybound(float[] values, float dy) {
      float height = getheight();
      if (mimageheight * values[matrix.mscale_y] < height)
        return 0;
      if (values[matrix.mtrans_y] + dy > 0)

        dy = -values[matrix.mtrans_y];

      else if (values[matrix.mtrans_y] + dy < -(mimageheight
          * values[matrix.mscale_y] - height))

        dy = -(mimageheight * values[matrix.mscale_y] - height)

            - values[matrix.mtrans_y];

      return dy;

    }

    private float checkdxbound(float[] values, float dx, float dy) {

      float width = getwidth();

      if (!mleftdragable && dx < 0) {

        if (math.abs(dx) * 0.4f > math.abs(dy) && mfirstmove) {

          stopdrag();

        }

        return 0;

      }
      if (!mrightdragable && dx > 0) {
        if (math.abs(dx) * 0.4f > math.abs(dy) && mfirstmove) {
          stopdrag();
        }
        return 0;
      }
      mleftdragable = true;

      mrightdragable = true;

      if (mfirstmove)

        mfirstmove = false;

      if (mimagewidth * values[matrix.mscale_x] < width) {

        return 0;

      }

      if (values[matrix.mtrans_x] + dx > 0) {

        dx = -values[matrix.mtrans_x];

      } else if (values[matrix.mtrans_x] + dx < -(mimagewidth

          * values[matrix.mscale_x] - width)) {

        dx = -(mimagewidth * values[matrix.mscale_x] - width)

            - values[matrix.mtrans_x];

      }

      return dx;

    }

    private void setzoommatrix(motionevent event) {

      if (event.getpointercount() < 2)
        return;

      float enddis = distance(event);
      if (enddis > 10f) {
        float scale = enddis / mstartdis;
        mstartdis = enddis;
        mcurrentmatrix.set(getimagematrix());
        float[] values = new float[9];
        mcurrentmatrix.getvalues(values);
        scale = checkmaxscale(scale, values);
        pointf centerf = getcenter(scale, values);
        mcurrentmatrix.postscale(scale, scale, centerf.x, centerf.y);
        setimagematrix(mcurrentmatrix);
      }
    }
    private pointf getcenter(float scale, float[] values) {
      if (scale * values[matrix.mscale_x] < mscale || scale >= 1) {
        return new pointf(getwidth() / 2, getheight() / 2);
      }
      float cx = getwidth() / 2;
      float cy = getheight() / 2;
      if ((getwidth() / 2 - values[matrix.mtrans_x]) * scale < getwidth() / 2)
        cx = 0;
      if ((mimagewidth * values[matrix.mscale_x] + values[matrix.mtrans_x])
          * scale < getwidth())

        cx = getwidth();

      return new pointf(cx, cy);

    }
    private float checkmaxscale(float scale, float[] values) {

      if (scale * values[matrix.mscale_x] > max_scale)
        scale = max_scale / values[matrix.mscale_x];
      return scale;
    }
    private void resetmatrix() {
      if (checkrest()) {
        mcurrentmatrix.set(mmatrix);
        setimagematrix(mcurrentmatrix);
      } else {
        float[] values = new float[9];
        getimagematrix().getvalues(values);
        float height = mimageheight * values[matrix.mscale_y];
        if (height < getheight()) {
          float topmargin = (getheight() - height) / 2;
          if (topmargin != values[matrix.mtrans_y]) {
            mcurrentmatrix.set(getimagematrix());
            mcurrentmatrix.posttranslate(0, topmargin
                - values[matrix.mtrans_y]);
            setimagematrix(mcurrentmatrix);
          }
        }
      }
    }
    private boolean checkrest() {
      float[] values = new float[9];
      getimagematrix().getvalues(values);
      float scale = values[matrix.mscale_x];
      return scale < mscale;
    }
    private void ismatrixenable() {
      if (getscaletype() != scaletype.center) {

        setscaletype(scaletype.matrix);

      } else {
        mmode = mode_unable;
      }

    }
    private float distance(motionevent event) {

      float dx = event.getx(1) - event.getx(0);

      float dy = event.gety(1) - event.gety(0);

      return (float) math.sqrt(dx * dx + dy * dy);
    }
    public void ondoubleclick() {
      float scale = iszoomchanged() ? 1 : double_click_sacle;
      mcurrentmatrix.set(mmatrix);
      mcurrentmatrix.postscale(scale, scale, getwidth() / 2,
          getheight() / 2);
      setimagematrix(mcurrentmatrix);
    }
  }
  private class gesturelistener extends simpleongesturelistener {
    private final matrixtouchlistener mtouchlistener;
    public gesturelistener(matrixtouchlistener listener) {
      this.mtouchlistener = listener;
    }
    @override
    public boolean ondown(motionevent e) {
      return true;
    }
    @override
    public boolean ondoubletap(motionevent e) {

      mtouchlistener.ondoubleclick();
      return true;
    }
    @override
    public boolean onsingletapup(motionevent e) {
      return super.onsingletapup(e);
    }
    @override
    public void onlongpress(motionevent e) {
      super.onlongpress(e);
    }
    @override
    public boolean onscroll(motionevent e1, motionevent e2,

        float distancex, float distancey) {
      return super.onscroll(e1, e2, distancex, distancey);

    }
    @override
    public boolean onfling(motionevent e1, motionevent e2, float velocityx,
        float velocityy) {
      return super.onfling(e1, e2, velocityx, velocityy);
    }
    @override
    public void onshowpress(motionevent e) {
      super.onshowpress(e);
    }
    @override
    public boolean ondoubletapevent(motionevent e) {
      return super.ondoubletapevent(e);
    }
    @override
    public boolean onsingletapconfirmed(motionevent e) {
      if (msingletaplistener != null)
        msingletaplistener.onsingletap(e);
      return super.onsingletapconfirmed(e);
    }
  }
  public interface onmovinglistener {
    public void startdrag();

    public void stopdrag();
  }
  public interface onsingletaplistener {
    public void onsingletap(motionevent e);
  }
}

我对其中定义onsingletaplistener接口的方法稍作了一些修改,为onsingletap回调方法增加了motionevent类型的参数,来方便我们根据用户具体的事件内容作出对应的控制。

以上就是本文的全部内容,希望对大家学习android软件编程有所帮助。