点击打开进入应用的动画(点击非Android View)
android点击一个View进入一个应用,通常会有好几种动画,可以通过xml控制,也可以通过其内部提供的ActivityOptions类来控制。那么最近我们的载体(一个桌面)需要使用ActivityOptions.makeScaleUpAnimation的动画方式来进入一个应用,如果我们点击的是一个View v,那么正常的程序可以是酱紫:
Intent intent = 。。。 int[] pos = new int[2]; v.getLocationOnScreen(pos); intent.setSourceBounds(new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight())); ActivityOptions opts = ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); startActivity(intent, opts.toBundle());
?上述效果就是点击一个图标(一个View)然后就进入到一个应用,中间的这个过程的动画效果就是伤处的opts控制滴,所以这种方法还是蛮简单的。那么问题来了,我点击的不是View怎么办?其实在桌面上的东西都是View,只不过我们的东西有点特别,opengl实现的,整体的内容是一个View,但是内部的空间没有一个是View的子类,那怎么办咯?例如amigo随变桌面里的创意时钟就是酱紫的,这整张图是一个View,内部的却不是View,又要求以点击的部位弹出应用,而不是以整个View弹出:
首先可以看到startActivity的第一个参数intent需要的内容,它就是需要4个int类型的值,而且分别是左上角的x坐标,左上角的y坐标,长度,宽度,好吧,这4个值都可以自己给值了。
再看到startActivity的第二个参数,一个Bundle对象,然后我们就进入到了ActivityOptions的源码看到toBundle方法,其实就是要传一些键值对:
public Bundle toBundle() { if (mAnimationType == ANIM_DEFAULT) { return null; } Bundle b = new Bundle(); if (mPackageName != null) { b.putString(KEY_PACKAGE_NAME, mPackageName); } b.putInt(KEY_ANIM_TYPE, mAnimationType); switch (mAnimationType) { case ANIM_CUSTOM: case ... ... } return b; }
??再看makeScaleUpAnimation方法:
public static ActivityOptions makeScaleUpAnimation(View source, int startX, int startY, int width, int height) { ActivityOptions opts = new ActivityOptions(); opts.mPackageName = source.getContext().getPackageName(); opts.mAnimationType = ANIM_SCALE_UP; int[] pts = new int[2]; source.getLocationOnScreen(pts); opts.mStartX = pts[0] + startX; opts.mStartY = pts[1] + startY; opts.mWidth = width; opts.mHeight = height; return opts; }
?可以看到这个View v的作用:1.获取当前应用的包名;2.获取这个view在屏幕上的左上角的坐标
结合上述两个源码,我们再次进入到toBundle,找到mAnimationType = ANIM_SCALE_UP需要的简直对:
?
b.putString(KEY_PACKAGE_NAME, mPackageName);//这个自己可以获取 b.putInt(KEY_ANIM_TYPE, mAnimationType);//ANIM_SCALE_UP常量 case ANIM_SCALE_UP: b.putInt(KEY_ANIM_START_X, mStartX); b.putInt(KEY_ANIM_START_Y, mStartY); b.putInt(KEY_ANIM_WIDTH, mWidth); b.putInt(KEY_ANIM_HEIGHT, mHeight); break;
?好吧,由此可见需要的键值对一共有6个,另外需要的就是动画起始的坐标和初始框框的长度与宽度,其中长度和宽度我们可以自己给个固定的值,那么接下来就是mStartX和mStartY怎么获取?
?
其实它的源码写的很清楚了
?
int[] pts = new int[2]; View.getLocationOnScreen(pts);
?通过上述方法可以得到一个View控制的左上角的坐标,但是这里的值并非我们想要的,我们需要点击例如上图的右下角那个图标呢? 不可能以整个View来弹出吧,所以还需要详细的点击的坐标。好在onTouchEvent(MotionEvent event)中的event可以得到当前点击的view中的坐标
?
event.getX()得到该点击在View中的坐标,又View在屏幕上的左上角的坐标是pts[0],那就是说 x=event.getX()+pts[0]就是我所点击的点在屏幕上的x坐标,由此y=event.getY()+pts[1]是我所点击的点在屏幕上的Y坐标,再给个定值长度和宽度=20,那就可以得到想要的Bundle了。
?
Bundle b = new Bundle(); b.putString(KEY_PACKAGE_NAME, packageName); b.putInt(KEY_ANIM_TYPE, ANIM_SCALE_UP); b.putInt(KEY_ANIM_START_X, x); b.putInt(KEY_ANIM_START_Y, y); b.putInt(KEY_ANIM_WIDTH, constVlaue); b.putInt(KEY_ANIM_HEIGHT, constVlaue);
?
Context.startActivity(intent, b);
?好吧,虽然废话了一大把,但还是写出来作为一个记录,让自己以后养成查看源码的习惯,不要害怕,,,
?
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。