雅虎过度效果
来源:互联网 发布:台湾大学知乎 编辑:程序博客网 时间:2024/05/22 11:58
这是我以前在做雅虎界面效果的代码,废话不多说,直接上代码:
1、主界面:(没有xml布局,都是通过代码实现):
public class MainActivity extends Activity { private SplashView mSplashView; private FrameLayout mMainView; private Handler mHandler = new Handler(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //先放动画加载界面 mMainView = new FrameLayout(getApplicationContext());//帧布局 mSplashView = new SplashView(getApplicationContext());//自定义动画view mMainView.addView(mSplashView); setContentView(mMainView); //模拟后台加载数据 startLoadingData(); } /** 延迟3s */ private void startLoadingData() { //开线程 mHandler.postDelayed( new Runnable() { @Override public void run() { // 加载完毕--- onLoadingDataEnd(); } }, 3000);//延迟时间 } /** 执行其余动画 */ protected void onLoadingDataEnd() { //开始其他的动画---第二部分的动画 //注意:动画界面已经提前在了,并且动画对象在执行时不会被覆盖掉,只有执行完了才被主界面覆盖 mSplashView.splashAndDisapper(); //再放显示布局界面 ContentView mContentView = new ContentView(this);//ImageView mMainView.addView(mContentView,0);//位置为0,同动画位置,直接覆盖动画界面 }}
2、 ImageView类(相当于new ImageView(this))
public class ContentView extends ImageView { public ContentView(Context context) { super(context); //设置了一张图片 setImageResource(R.drawable.content); }}
3、继承View的主要动画实现类
/** * 自定义view * * @author weica * 说明: * 1.先在构造函数中执行第一次旋转动画 * 2.然后再主线程的定时器方法完成后,调用第二个6圆缩放动画, * 以此类推,到中心圆缩放动画,到扩散动画,最后显示主界面 * */public class SplashView extends View { /** some adjustable parameters **/ // 大圆(里面包含很多小圆的)的半径 private float mRotationRadius = 90; // 每一个小圆的半径 private float mCircleRadius = 18; // 小圆圈的颜色列表,在initialize方法里面初始化 private int[] mCircleColors; // 大圆和小圆旋转的时间 private long mRotationDuration = 1200; // ms // 第二部分动画的执行总时间(包括三个动画时间,各占1/3) private long mSplashDuration = 1200; // ms // 整体的背景颜色 private int mSplashBgColor = Color.WHITE; /** * 参数,保存了一些绘制状态,会被动态地改变* */ // 空心圆初始半径 private float mHoleRadius = 0F; // 当前大圆旋转角度(弧度) private float mCurrentRotationAngle = 0F; // 当前大圆的半径 private float mCurrentRotationRadius; // 当前单圆的半径 private float mCurrentSingleCircleRadius; // 保存当前动画状态--当前在执行哪种动画 private SplashState mState = null; // 绘制圆的画笔 private Paint mPaint = new Paint(); // 绘制背景的画笔 private Paint mPaintBackground = new Paint(); // 屏幕正中心点坐标 private float mCenterX; private float mCenterY; // 屏幕对角线一半 private float mDiagonalDist; //控件的宽高可以从这个方法中取 @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mCenterX = w / 2f; mCenterY = h / 2f; mDiagonalDist = (float) (Math.sqrt(w * w + h * h) / 2); } /** * 构造方法 * * @param context */ public SplashView(Context context) { super(context); // 初始化 initialize(context); } private void initialize(Context context) { // 色值数组 mCircleColors = context.getResources().getIntArray( R.array.splash_circle_colors); // 给SplashView设置一个默认的背景--透明 // setBackgroundColor(Color.TRANSPARENT); // 设置画笔 // 消除锯齿 mPaint.setAntiAlias(true); mPaintBackground.setAntiAlias(true); // STROKE描边,空心效果 mPaintBackground.setStyle(Paint.Style.STROKE); // 设置默认背景颜色颜色(背景画笔设置默认设置,Color.WHITE) mPaintBackground.setColor(mSplashBgColor); } /** * 定义一个抽象类--动画状态类 作用:让几个动画状态类开始执行后都开始绘制各自的界面--invalidate--》onDraw() * 通过onDraw方法统一控制调用drawstate方法来绘制界面 * */ private abstract class SplashState {// 接收对象---》mState public abstract void drawState(Canvas canvas); } // 每次界面刷新都会调用的--绘制 @Override protected void onDraw(Canvas canvas) { // canvas画布,paint画笔 // super.onDraw(canvas); if (mState == null) { // 第一次执行的动画 handleFirstDraw(); } // 分发到各个动画状态类---绘制各自的图像 mState.drawState(canvas); } /** 第一次执行的动画,设置默认执行的动画对象 */ private void handleFirstDraw() { //默认执行一次第一个旋转动画,给mState赋值 mState = new RotationState(); // 第一次执行动画,需要出示一些默认参数 // 大圆当前旋转角度 mCurrentRotationAngle = 0f; // 设置默认的空心圆的半径 mHoleRadius = 0f; // 默认设置当前大圆的半径 mCurrentRotationRadius = mRotationRadius; // 默认设置当前单圆半径 mCurrentSingleCircleRadius = mCircleRadius; } /** * 定义第一个动画---旋转动画 大圆( 包含了6个小圆) (继承抽象类的子类,其中把drawState方法写好,等待onDraw调用方法) */ private class RotationState extends SplashState { private ValueAnimator mAnimator;// 属性动画 /** 构造方法 */ public RotationState() { // 圆心角弧度变化 0到360 mAnimator = ValueAnimator.ofFloat(0, (float) (Math.PI * 2)); mAnimator.setDuration(mRotationDuration);// 设置默认的旋转时间 1200ms // 使用线性插值器LinearInterpolator可以让动画平滑地执行 mAnimator.setInterpolator(new LinearInterpolator()); // 设置监听 mAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { // 当前大圆旋转角度(弧度) mCurrentRotationAngle = (Float) animation .getAnimatedValue(); // 刷新界面,重新绘制界面--onDraw invalidate(); } }); // 重复次数为无穷 mAnimator.setRepeatCount(ValueAnimator.INFINITE); // 设置让他不断地旋转 --循环 mAnimator.setRepeatMode(ValueAnimator.RESTART); // 开始执行 mAnimator.start(); } @Override public void drawState(Canvas canvas) { // 绘制界面--根据旋转情况来绘制界面---坐标!时间! // 绘制背景 drawBackground(canvas); // 绘制里面的小圆 drawCircles(canvas); } public void cancel() { mAnimator.cancel(); } } /** 绘制大圆背景 */ public void drawBackground(Canvas canvas) { // 绘制splashview的背景 if (mHoleRadius > 0f) { /** * 绘制空心圆的技巧 */ float strokeWidth = mDiagonalDist - mHoleRadius;// 屏幕对角线一半 空心圆初始半径0F float circleRadius = mHoleRadius + strokeWidth / 2;// 空心圆初始半径 // 屏幕对角线一半的一半 // 绘制边框(width)--里面是空心的 mPaintBackground.setStrokeWidth(strokeWidth); // 原点:屏幕中心点 半径:屏幕对角线一半的一半 背景画笔:mPaintBackground canvas.drawCircle(mCenterX, mCenterY, circleRadius, mPaintBackground); } else { canvas.drawColor(mSplashBgColor); } } /** 绘制里面的小圆 */ public void drawCircles(Canvas canvas) { // 绘制小圆 --遍历6个小圆 int numCircles = mCircleColors.length;// 色值数组大小 // 小圆之间的间隔角度 360/6就是每个小圆的夹角大小 float rotationAngle = (float) (2 * Math.PI / numCircles); for (int i = 0; i < numCircles; i++) { // 得到某个小圆的坐标 // 每一个小圆的弧度 = 当前大圆整体旋转了多少度 + i*小圆之间的间隔角度 double angle = mCurrentRotationAngle + (i * rotationAngle); // 下面计算小圆在弧度不断改变的情况下,圆心的坐标位置 double circleX = mCenterX + mCurrentRotationRadius * Math.cos(angle); double circleY = mCenterY + mCurrentRotationRadius * Math.sin(angle); // 设置颜色 mPaint.setColor(mCircleColors[i]); // 根据小圆的坐标点绘制小圆 canvas.drawCircle((float) circleX, (float) circleY, mCircleRadius, mPaint); } } /** * 定义第二个动画---6个小圆聚合动画 */ private class MergingState extends SplashState { public MergingState() { // 聚合范围:0~大圆的半径 0~90 ValueAnimator animator = ValueAnimator.ofFloat(0, mRotationRadius); animator.setDuration(mSplashDuration / 3);// 1200/3 // 设置监听 animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animator) { // 当前大圆的旋转半径(当前半径对象,可变) mCurrentRotationRadius = (Float) animator .getAnimatedValue(); invalidate(); } }); // 设置监听-- animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); // 动画结束--进入下一个动画 3(中心圆再缩放一下) mState = new SingularityState(); // mState = new ExpandingState();//动画4,扩散动画 } }); // 插值器(Interpolator)弹射的效果,注意:缩放动画就是因为这个属性会先变大一下再缩小 animator.setInterpolator(new OvershootInterpolator(6f)); // 保持动画执行后的状态 animator.reverse(); } @Override public void drawState(Canvas canvas) { // 绘制界面--根据旋转情况来绘制界面---坐标!时间! // 背景绘制 drawBackground(canvas); // 处理小圆 drawCircles(canvas); } } /** * 定义第三个动画---(为了更加美观,最好处理一下缩放后,中心点的圆再进行缩放) 中心点位置单独的圆的缩放动画效果 */ private class SingularityState extends SplashState { public SingularityState() { // 0~单圆的半径 0~18 ValueAnimator animator = ValueAnimator.ofFloat(0, mCircleRadius); animator.setDuration(mSplashDuration / 3); animator.setInterpolator(new OvershootInterpolator(6f)); animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { // 单圆的半径 mCurrentSingleCircleRadius = (Float) animation .getAnimatedValue(); invalidate(); } }); // 监听 animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); // 执行下一个动画,动画4,扩散动画 mState = new ExpandingState(); } }); animator.reverse(); } @Override public void drawState(Canvas canvas) { // 绘制界面--根据旋转情况来绘制界面---坐标!时间! drawBackground(canvas); // 画单圆 drawSingleCircle(canvas); } } /** * 定义第四个动画--- 空心圆动画 */ private class ExpandingState extends SplashState { public ExpandingState() { ValueAnimator animator = ValueAnimator.ofFloat(0, mDiagonalDist); // 减速效果 animator.setInterpolator(new DecelerateInterpolator()); animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mHoleRadius = (Float) animation.getAnimatedValue(); invalidate(); } }); animator.start(); } @Override public void drawState(Canvas canvas) { // 绘制界面--根据旋转情况来绘制界面---坐标!时间! drawBackground(canvas); } } /** * (暴露的方法,其余动画的入口) * 执行第二部分的动画然后消失,显示contentview */ public void splashAndDisapper() { // mState不为null,并且是第一个动画实例 if (mState != null && mState instanceof RotationState) { RotationState rs = (RotationState) mState; rs.cancel();// 停止旋转动画 // 开始下一个动画(聚合动画) // 开线程放到消息队列里面,为了不影响主UI线程的响应 post(new Runnable() { @Override public void run() { mState = new MergingState(); } }); } } /** 画单圆 */ public void drawSingleCircle(Canvas canvas) { mPaint.setColor(mCircleColors[1]);// 中心圆的背景颜色值 canvas.drawCircle(mCenterX, mCenterY, mCurrentSingleCircleRadius, mPaint); }}
以上就是全部代码,大家可以自个去试试,有什么问题可以留言。或者在微信公众号“技术帮团队”上找我们。
0 0
- 雅虎过度效果
- 状态过度效果
- 视图翻页过度效果
- Javascript 地图过度效果
- css3过度效果
- css过度效果
- vue 过度效果1
- Tweening过度缓动效果
- cocos2dx【Scene场景过度效果】
- element ui 加载过度效果
- 立方体的着色,阴影效果,过度效果
- 雅虎天气的那个效果
- 切换两个activity时过度动画效果
- Android TransitionDrawable ImageView过度效果使用实例
- 转场动画过度效果 (私有API)
- jquery.easing.js 使用动画过度效果
- css3实现web app翻页过度效果
- 过度动画效果,突然没了。
- 图像编程总结
- 使用富文本SpannableString实现标签
- 依赖注入
- 网易笔试题:比较重量
- 基础知识补漏-控制文件和引导
- 雅虎过度效果
- 移植u-boot2012.04.1 -》2440 (三)nandflash 识别
- Page directive: invalid value for import
- ThinkPHP框架整合环信即时通讯DEMO
- UIView坐标转换
- 使用chart.js添加动态背景图
- Android电话系统rild-概述篇
- 易宝支付为二清机构放开通道,导致POS代理机构卷款跑路
- 画一个渐变的圆环