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,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,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,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,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,15,20));
浮物”时:floatBackground.addfloatVIEw(new floatText( 0.3f,“E”))
接收的三个参数分别为出生位置在屏幕宽的百分比,长的百分比,和显示的文字。
Github
https://github.com/a396901990/FloatBackground
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
总结以上是内存溢出为你收集整理的Android漂浮背景效果的制作方法全部内容,希望文章能够帮你解决Android漂浮背景效果的制作方法所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)