700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > android 自定义ImageView实现图片手势滑动 多点触摸放大缩小效果

android 自定义ImageView实现图片手势滑动 多点触摸放大缩小效果

时间:2020-10-12 11:45:03

相关推荐

android 自定义ImageView实现图片手势滑动 多点触摸放大缩小效果

分享一下我老师大神的人工智能教程!零基础,通俗易懂!/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

转自:/jj120522/article/details/8467810

首先呢,还是一贯作风,我们先来看看众多应用中的示例:(这种效果是很常见的,可以说应用的必须品.)

搜狐客户端 百度新闻客户端新浪微博凤凰新闻客户端

也许大家对这些客户端并不陌生,但是不知道大家有没有注意到这些不足之处呢,这里我就叨唠吓这些不人性化的地方.

首先搜狐:她的图片放大后(未铺满屏幕)可以上下来回拖动,这点肯定是不允许的.感慨搜狐你在移动新闻界这么有名气,莫非是故意如此吗?

百度客户端:你看她的图片不用我多说了吧,其实我还可以继续在缩,这里我要狠狠批判一下百度,因为你那么牛叉的公司,为什么这点bug就查不出来,用户体验相当不好.

新浪微博:她的图片可以缩放到这个程度,没有回缩动画,我个人感觉最好有回缩动画的,毕竟用户不可能看你家图的时候将之缩放成小图看吧.(或许用户在放大后想缩回原先图片而此时缩回头了,所以我们应该弄一个回缩动画.)

凤凰新闻客户端:这家应用更离谱,就没有放大缩小等操作,就一个傻傻的图片呆在那,更离谱的是我(无意)触碰一下图片就返回了.(我要是用户的话,就先不说你家没有放大缩小等操作吧,倘若我想仔细观看这张美图的话,我手指不小心触碰一下,你Y的就给我关闭.大失雅兴,还有就是我点击文章图片切换到浏览图片页面时,你的加载页面太丑了,我简直看不下去,所以果断卸掉.)

其实网上也有几个做的比较好的,我没有上图,例如:腾讯微博,网易客户端,新浪微博等.做的都相当不错。

哈哈.说的有点过了,就叨唠到此,下面我们看下应该如何实现这种效果.说之前我在絮叨一下,这篇文章本来是打算.12.31发布的留个纪念,谁知这玩意我弄了一天没有弄出来,后来放弃了,长时间没有弄出来心情也没有了,直到.01.04也就是昨天又接着弄了将近一天,到晚上11点了还没有解决.一怒之下CF玩到1点睡觉去了.该死的破玩意想留个纪念也不让.今天下午有时间就又接着搞.功夫不负有心人啊.没想到解决了.我郁闷了个去.所以这篇文章来之不易啊,如果看到该文章并且对你有帮助的话,记得赞一个.

网上文章虽多,但是这种效果少之又少.我真诚的献上以供同根生的苦逼程序员.

实现原理:自定义ImageView对此控件进行相应的layout(动态布局).

这里你要明白几个方法执行的流程:首先ImageView是继承自View的子类.

onLayout方法:是一个回调方法.该方法会在在View中的layout方法中执行,在执行layout方法前面会首先执行setFrame方法.

setFrame方法:判断我们的View是否发生变化,如果发生变化,那么将最新的l,t,r,b传递给View,然后刷新进行动态更新UI.并且返回ture.没有变化返回false.

在介绍自定义控件之前,我们先要明白我们要获取哪些数据:屏幕的宽度,屏幕的高度.(这里其实你也可以对LinerLayout进行ViewTreeObserver监听获取其宽高度.),原始图片本身的宽度及高度.以及我们缩放的最大最小值.

首先我们要重写setImageBitmap方法.作用:获取图片的宽高,求出缩放极限值.

[java]viewplain copy /****设置显示图片*/@OverridepublicvoidsetImageBitmap(Bitmapbm){super.setImageBitmap(bm);/**获取图片宽高**/bitmap_W=bm.getWidth();bitmap_H=bm.getHeight();MAX_W=bitmap_W*3;MAX_H=bitmap_H*3;MIN_W=bitmap_W/2;MIN_H=bitmap_H/2;}

接着我们在onLayout方法中我们获取最初的l,t,r,b.

[java]viewplain copy @OverrideprotectedvoidonLayout(booleanchanged,intleft,inttop,intright,intbottom){super.onLayout(changed,left,top,right,bottom);if(start_Top==-1){start_Top=top;start_Left=left;start_Bottom=bottom;start_Right=right;}}

下面我们说下重点Touch方法.其实原来大家都明白,要说难的话估计就是逻辑实现了.

说之前大家要明白单点与多点的区别:

单手指操作:ACTION_DOWN---ACTION_MOVE----ACTION_UP

多手指操作:ACTION_DOWN---ACTION_POINTER_DOWN---ACTION_MOVE--ACTION_POINTER_UP---ACTION_UP.

上面只是简单说下流程,详细请大家自行研究,这里只是讲解如果运用.

[java]viewplain copy /****touch事件*/@OverridepublicbooleanonTouchEvent(MotionEventevent){/**处理单点、多点触摸**/switch(event.getAction()&MotionEvent.ACTION_MASK){caseMotionEvent.ACTION_DOWN:onTouchDown(event);break;//多点触摸caseMotionEvent.ACTION_POINTER_DOWN:onPointerDown(event);break;caseMotionEvent.ACTION_MOVE:onTouchMove(event);break;caseMotionEvent.ACTION_UP:mode=MODE.NONE;break;//多点松开caseMotionEvent.ACTION_POINTER_UP:mode=MODE.NONE;/**执行缩放还原**/if(isScaleAnim){doScaleAnim();}break;}returntrue;} 这里的实现我都分开写了,利于大家的观看,在这里我顺便说一下自定义控件返回值: 如果对于没有孩子的控件,如果要对Touch处理最好return true.这样也是游戏开发中经常用的,如果该控件有孩子的话,可不要这么弄,不然孩子会监听不到Touch事件.

下面我们一个一个方法的看:

onTouchDown:获取手指点击时候的起始坐标.

[java]viewplain copy /**按下**/voidonTouchDown(MotionEventevent){mode=MODE.DRAG;current_x=(int)event.getRawX();current_y=(int)event.getRawY();start_x=(int)event.getX();start_y=current_y-this.getTop();} 这里大家也要明白event.getRawX()和event.getX(),不过我相信大家都明白的,我前面那篇ListView拖拽也提到过.一个相对屏幕,一个相对父控件.

onPointerDown:两手指之间的距离.

[java]viewplain copy /**两个手指只能放大缩小**/voidonPointerDown(MotionEventevent){if(event.getPointerCount()==2){mode=MODE.ZOOM;beforeLenght=getDistance(event);//获取两点的距离}} onTouchMove:移动的处理.[java]viewplain copy /**移动的处理**/voidonTouchMove(MotionEventevent){intleft=0,top=0,right=0,bottom=0;/**处理拖动**/if(mode==MODE.DRAG){/**在这里要进行判断处理,防止在drag时候越界**//**获取相应的l,t,r,b**/left=current_x-start_x;right=current_x+this.getWidth()-start_x;top=current_y-start_y;bottom=current_y-start_y+this.getHeight();/**水平进行判断**/if(isControl_H){if(left>=0){left=0;right=this.getWidth();}if(right<=screen_W){left=screen_W-this.getWidth();right=screen_W;}}else{left=this.getLeft();right=this.getRight();}/**垂直判断**/if(isControl_V){if(top>=0){top=0;bottom=this.getHeight();

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。