当前位置: 移动技术网 > 移动技术>移动开发>Android > Android实现手势控制ImageView图片大小

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

本文实例实现的主要功能是在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软件编程有所帮助。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网