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漂浮背景效果的制作方法

相关文章:

你感兴趣的文章:

标签云: