您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 人事档案/员工关系 > Android 3D滑动菜单实现及源代码
Android3D滑动菜单完全解析,实现推拉门式的立体特效在上一篇文章中,我们学习了Camera的基本用法,并借助它们编写了一个例子,实现了类似于APIDemos里的图片中轴旋转功能。不过那个例子的核心代码是来自于APIDemos中带有的Rotate3dAnimation这个类,是它帮助我们完成了所有的三维旋转操作,所有Matrix和Camera相关的代码也是封装在这个类中。这样说来的话,大家心里会不会痒痒的呢?虽然学习了Camera的用法,但却没有按照自己的理解来实现一套非常炫酷的3D效果。不要着急,今天我就带着大家一起来实现一种3D推拉门式的滑动菜单,而且完全不会借助任何APIDemos里面的代码。当然如果你还不是很了解Camera的使用方式,可以先去阅读我的上一篇文章Android中轴旋转特效实现,制作别样的图片浏览器。关于滑动菜单的文章我也已经写过好几篇了,相信看过的朋友对滑动菜单的实现方式应该都已经比较熟悉了,那么本篇文章的重点就在于,如何在传统滑动菜单的基础上加入推拉门式的立体效果。还不了解滑动菜单如何实现的朋友,可以去翻一翻我之前的文章。说到这里我必须要吐槽一下了,最近发现有不少的网站和个人将我的文章恶意转走,而且还特意把第一行的原文地址信息去除掉。更可气的是,在百度上搜索我文章的标题时,竟然先找到的是那些转载我文章的网站。唉,伤心了,看来还是谷歌比较正常。因此今天我也是在这里特别申明一下,我所写的所有文章均是首发于CSDN博客,如果你阅读这篇文章时是在别的网站,那么你将无法找到我前面所写的关于传统滑动菜单的文章,而且你的疑问和留言也将得不到解答。下面还是回到正题,首先来讲一下这次的实现原理吧,其实传统的滑动菜单功能就是把菜单部分放在了下面,主布局放在了上面,然后根据手指滑动的距离来偏移主布局,让菜单部分得以显示出来就行了。不过我们这次既然要做推拉门式的立体效果,就需要将传统的思维稍微转变一下,可以先让菜单部分隐藏掉,但却复制一个菜单的镜像并生成一张图片,然后在手指滑动的时候对这张图片进行三维操作,让它产生推拉门式的效果,等滑动操作结束的时候,才让真正的菜单显示出来,然后将这个图片隐藏。原理示意图如下所示:那么下面我们就开始动手实现吧,首先新建一个Android项目,起名叫做ThreeDSlidingLayoutDemo。然后新建一个Image3dView类继承自View,用于生成镜像图片,以及完成三维操作,代码如下所示:[java]viewplaincopy1.publicclassImage3dViewextendsView{2.3./**4.*源视图,用于生成图片对象。5.*/6.privateViewsourceView;7.8./**9.*根据传入的源视图生成的图片对象。10.*/11.privateBitmapsourceBitmap;12.13./**14.*源视图的宽度。15.*/16.privatefloatsourceWidth;17.18./**19.*Matrix对象,用于对图片进行矩阵操作。20.*/21.privateMatrixmatrix=newMatrix();22.23./**24.*Camera对象,用于对图片进行三维操作。25.*/26.privateCameracamera=newCamera();27.28./**29.*Image3dView的构造函数30.*31.*@paramcontext32.*@paramattrs33.*/34.publicImage3dView(Contextcontext,AttributeSetattrs){35.super(context,attrs);36.}37.38./**39.*提供外部接口,允许向Image3dView传入源视图。40.*41.*@paramview42.*传入的源视图43.*/44.publicvoidsetSourceView(Viewview){45.sourceView=view;46.sourceWidth=sourceView.getWidth();47.}48.49./**50.*清除掉缓存的图片对象。51.*/52.publicvoidclearSourceBitmap(){53.if(sourceBitmap!=null){54.sourceBitmap=null;55.}56.}57.58.@Override59.protectedvoidonDraw(Canvascanvas){60.super.onDraw(canvas);61.if(sourceBitmap==null){62.getSourceBitmap();63.}64.//计算图片需要旋转的角度65.floatdegree=90-(90/sourceWidth)*getWidth();66.camera.save();67.camera.rotateY(degree);68.camera.getMatrix(matrix);69.camera.restore();70.//将旋转的中心点移动到屏幕左边缘的中间位置71.matrix.preTranslate(0,-getHeight()/2);72.matrix.postTranslate(0,getHeight()/2);73.canvas.drawBitmap(sourceBitmap,matrix,null);74.}75.76./**77.*获取源视图对应的图片对象。78.*/79.privatevoidgetSourceBitmap(){80.if(sourceView!=null){81.sourceView.setDrawingCacheEnabled(true);82.sourceView.layout(0,0,sourceView.getWidth(),sourceView.getHeight());83.sourceView.buildDrawingCache();84.sourceBitmap=sourceView.getDrawingCache();85.}86.}87.88.}可以看到,Image3dView中提供了一个setSourceView()方法,用于传递源视图进来,我们稍后复制镜像就是对它进行复制。然后在onDraw()方法里对sourceBitmap进行判断,如果为空,则去调用getSourceBitmap()方法来生成一张镜像图片,getSourceBitmap()方法的细节大家自己去看。在获得了镜像图片之后,接下来就是要计算图片的旋转角度了,这里根据Image3dView当前的宽度和源视图的总宽度进行对比,按比例算出旋转的角度。然后调用Camera的rotateY()方法,让图片团练Y轴进行旋转,并将旋转的中心点移动到屏幕左边缘的中间位置,这几行代码我们在上篇文章中已经见过了,算是挺熟悉了吧!最后调用Canvas的drawBitmap()方法把图片绘制出来。完成了Image3dView之后,接着我们要开始编写滑动菜单部分的代码,其实这次的代码和之前的滑动菜单代码大同小异,看过我前面文章的朋友,这次理解起来一定会轻而易举。新建ThreeDSlidingLayout类,代码如下所示:[java]viewplaincopy1.publicclassThreeDSlidingLayoutextendsRelativeLayoutimplementsOnTouchListener{2.3./**4.*滚动显示和隐藏左侧布局时,手指滑动需要达到的速度。5.*/6.publicstaticfinalintSNAP_VELOCITY=200;7.8./**9.*滑动状态的一种,表示未进行任何滑动。10.*/11.publicstaticfinalintDO_NOTHING=0;12.13./**14.*滑动状态的一种,表示正在滑出左侧菜单。15.*/16.publicstaticfinalintSHOW_MENU=1;17.18./**19.*滑动状态的一种,表示正在隐藏左侧菜单。20.*/21.publicstaticfinalintHIDE_MENU=2;22.23./**24.*记录当前的滑动状态25.*/26.privateintslideState;27.28./**29.*屏幕宽度值。30.*/31.privateintscreenWidth;32.33./**34.*右侧布局最多可以滑动到的左边缘。35.*/36.privateintleftEdge=0;37.38./**39.*右侧布局最多可以滑动到的右边缘。40.*/41.privateintrightEdge=0;42.43./**44.*在被判定为滚动之前用户手指可以移动的最大值。45.*/46.privateinttouchSlop;47.48./**49.*记录手指按下时的横坐标。50.*/51.privatefloatxDown;52.53./**54.*记录手指按下时的纵坐标。55.*/56.privatefloatyDown;57.58./**59.*记录手指移动时的横坐标。60.*/61.privatefloatxMove;62.63./**64.*记录手指移动时的纵坐标。65.*/66.privatefloatyMove;67.68./**69.*记录手机抬起时的横坐标。70.*/71.privatefloatxUp;72.73./**74.*左侧布局当前是显示还是隐藏。只有完全显示或隐藏时才会更改此值,滑动过程中此值无效。75.*/76.privatebooleanisLeftLayoutVisible;77.78./**79.*是否正在滑动。80.*/81.privatebooleanisSliding;82.83./**84.*是否已加载过一次layout,这里onLayout中的初始化只需加载一次85.*/86.privatebooleanloadOnce;87.88./**89.*左侧布局对象。90.*/91.privateViewleftLayout;92.93./**94.*右侧布局对象。95.*/96.privateViewrightLayout;97.98./**99.*在滑动过程中展示的3D视图100.*/101.privateImage3dViewimage3dView;102.103./**104.*用于监听侧滑事件的View。105.*/106.privateViewmBindView;107.108./**109.*左侧布局的参数,通过此参数来重新确定左侧布局的宽度,以及更改leftMargin的值。110.*/111.privateMarginLayoutParamsleftLayoutParams;112.113./**114.*右侧布局的参数,通过此参数来重新确定右侧布局的宽度。115.*/116.privateMarginLayoutParamsrightLayoutParams;117.118./**119.*3D视图的参数,通过此参数来重新确定3D视图的宽度。120.*/121.privateViewGroup.LayoutParamsimage3dViewParams;122.123./**124.*用于计算手指滑动的速度。125.*/126.privateVelocityTrackermVelocityTracker;127.128./**129.*重写SlidingLayout的构造函数,其中获取了屏幕的宽度。130.*131.*@paramcontext132.*@paramattrs133.*/134.publicThreeDSlidingLayout(Contextcontext,AttributeSetattrs){135.super(context,attrs);136.WindowMana
本文标题:Android 3D滑动菜单实现及源代码
链接地址:https://www.777doc.com/doc-5448608 .html