ANDROID-漂浮背景效果

临文乍了了,彻卷兀若无。这篇文章主要讲述ANDROID-漂浮背景效果相关的知识,希望能为你提供帮助。
转载请注明本文出自大苞米的博客( http://blog.csdn.net/a396901990) , 谢谢支持!
效果图:
GIF动图效果不是很好, 实际效果非常平滑very smooth, 而且添加不同的图形可以组成各种效果, 目前已经用在我们项目的注册界面~

ANDROID-漂浮背景效果

文章图片

原理:
实现原理很简单, 每一个悬浮的“小物体”就是一个自定义View, 这些小的自定义View都盛放在一个自定义的ViewGroup中。然后所有的视图都放在这个ViewGroup之上, 这样就相当于做一个可动的背景。
下面结合代码详细介绍下:
详解: FloatObject
悬浮的物体, 继承自View, 需要重写onDraw方法, 主要作用就是来画出自己, 并进行随机曲线运动。
任何需要画出的对象都需要继承FloatObject, 并重写提供的drawFloatObject方法, 在此方法中可以通过设置画笔和画布画出任意图形。比如下面是画出一行文字:
public class FloatText extends FloatObject { String text; public FloatText(float posX, float posY, String text) { super(posX, posY); this.text = text; setAlpha(88); setColor(Color.WHITE); }@ Override public void drawFloatObject(Canvas canvas, float x, float y, Paint paint) { paint.setTextSize(65); canvas.drawText(text, x, y, paint); } }

随机曲线: 其实最复杂的部分就是让漂浮的物体做随机无规则的曲线运动, 并且每个漂浮物的速度不同, 这样整个漂浮动画才更加自然。
我之前想过使用布朗运动, 但是在网上找了好久也没找到一个好用的算法。
最后只能还是使用3点赛贝尔曲线, 使漂浮物沿着一条赛贝尔曲线运动, 达到终点时, 再随机产生一条新的曲线, 这样就可以实现随机曲线运动了。
控制运动的代码如下:
public void drawFloatItem(Canvas canvas) {switch (status) { case START: // fade in if (isFade() & & alpha < = ALPHA_LIMIT) { paint.setAlpha(alpha); alpha + = ALPHA_PER_FRAME; } else { setStatus(MOVE); } break; case MOVE: // 更新赛贝尔曲线点 if (mCurDistance = = 0) { start = new PointF(x, y); end = getRandomPoint((int)start.x, (int)start.y, (int) distance); // 取值范围distance c1 = getRandomPoint((int)start.x, (int)start.y, random.nextInt(width / 2)); // 取值范围width/2 c2 = getRandomPoint(end.x, end.y, random.nextInt(width / 2)); // 取值范围width/2 }// 计算塞贝儿曲线的当前点 PointF bezierPoint = CalculateBezierPoint(mCurDistance / distance, start, c1, c2, end); x = bezierPoint.x; y = bezierPoint.y; // 更新当前路径 mCurDistance + = MOVE_PER_FRAME; // 一段画完后重置 if (mCurDistance > = distance) { mCurDistance = 0; } break; case END: // fade out if (isFade() & & alpha > 0) { paint.setAlpha(alpha); alpha -= ALPHA_PER_FRAME; } else { setStatus(FINISH); } break; }if (status != FINISH) { Log.e(" drawFloatObject" , x+ " , " + y); drawFloatObject(canvas, x ,y, paint); } }

关于赛贝尔曲线运动的算法都是复用之前写的一篇文章ANDROID模拟火花粒子的滑动喷射效果, 如果大家有兴趣可以看看。
FloatBackground
FloatBackground继承自FrameLayout, 里面有一个用于存放FloatObject的集合。
FloatBackground的主要作用就是绘制所有的“漂浮物”, 以及维护其生命周期:
初始化:
private void initFloatObject(int width, int height) { for (FloatObject floatObject : floats) { int x = (int) (floatObject.posX * width); int y = (int) (floatObject.posY * height); floatObject.init(x, y, width, height); } }

绘制:
@ Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); for (FloatObject floatObject : floats) { floatObject.drawFloatItem(canvas); } // 隔一段时间重绘一次, 动画效果 getHandler().postDelayed(runnable, DELAY); }// 重绘线程 private Runnable runnable = new Runnable() { @ Override public void run() { invalidate(); // 控制帧数 } };

开始和结束:
public void startFloat() { for (FloatObject floatObject : floats) { floatObject.setStatus(FloatObject.START); } }public void endFloat() { for (FloatObject floatObject : floats) { floatObject.setStatus(FloatObject.END); } }

使用 使用时非常简单, 在layout文件中将FloatBackground设置为最底层的视图( 其实就是当作一个背景) :
< com.dean.library.FloatBackground android:id= " @ + id/float_view" android:layout_width= " match_parent" android:layout_height= " match_parent" > < LinearLayout android:layout_gravity= " center" android:layout_width= " match_parent" android:layout_height= " wrap_content" android:orientation= " vertical" > < Button android:id= " @ + id/start" android:layout_width= " wrap_content" android:layout_height= " wrap_content" android:layout_gravity= " center" android:text= " Start" /> < Button android:id= " @ + id/end" android:layout_width= " wrap_content" android:layout_height= " wrap_content" android:layout_gravity= " center" android:text= " End" /> < /LinearLayout> < /com.dean.library.FloatBackground>

在代码中进行如下调用:
final FloatBackground floatBackground = (FloatBackground) this.findViewById(R.id.float_view); Button start = (Button) this.findViewById(R.id.start); start.setOnClickListener(new View.OnClickListener() { @ Override public void onClick(View v) { floatBackground.startFloat(); } }); Button end = (Button) this.findViewById(R.id.end); end.setOnClickListener(new View.OnClickListener() { @ Override public void onClick(View v) { floatBackground.endFloat(); } }); floatBackground.addFloatView(new FloatRect(0.2f, 0.3f, 30, 40)); floatBackground.addFloatView(new FloatBitmap( this, 0.2f, 0.3f, R.drawable.gr_ptn_03)); floatBackground.addFloatView(new FloatCircle( 0.8f, 0.8f)); floatBackground.addFloatView(new FloatText( 0.3f, 0.6f, " E" )); floatBackground.addFloatView(new FloatRing( 0.6f, 0.2f, 15 ,20));

比如在添加文字“漂浮物”时: floatBackground.addFloatView(new FloatText( 0.3f, 0.6f, “E”))
接收的三个参数分别为出生位置在屏幕宽的百分比, 长的百分比, 和显示的文字。
Github
【ANDROID-漂浮背景效果】https://github.com/a396901990/FloatBackground

    推荐阅读