Android漂浮背景效果的制作方法
gif动图效果不是很好,实际效果非常平滑very smooth,而且添加不同的图形可以组成各种效果,目前已经用在我们项目的注册界面~
原理:
实现原理很简单,每一个悬浮的“小物体”就是一个自定义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
https://github.com/a396901990/floatbackground
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
android给RecyclerView加上折叠的效果示例
-
Android漂浮背景效果的制作方法
-
Android 中TextView中跑马灯效果的实现方法
-
Android实现美团、大众点评的购买悬浮效果(ScrollView滚动监听)
-
Android基于API的Tabs3实现仿优酷tabhost效果实例
-
Android实现腾讯新闻的新闻类别导航效果
-
Android编程实现设置按钮背景透明与半透明及图片背景透明的方法
-
Android中DialogFragment自定义背景与宽高的方法
-
Android PopWindow 设置背景亮度的实例
-
Android实现状态栏(statusbar)渐变效果的示例