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软件编程有所帮助。
下一篇: Android开发之资源文件用法实例总结
推荐阅读
-
Android手势滑动实现ImageView缩放图片大小
-
Android手势滑动实现两点触摸缩放图片
-
Android实现手势控制ImageView图片大小
-
[原创] 如何在android中实现swipe的手势功能及页面拖动动画 博客分类: Android AndroidSymbianC#C++C
-
Android实现ImageView阴影和图层效果
-
Android开发实现popupWindow弹出窗口自定义布局与位置控制方法
-
Android自定义GestureDetector实现手势ImageView
-
Android屏幕手势检测的实现代码
-
Android ImageView 固定宽高比例的实现方法
-
基于Android实现随手指移动的ImageView