Android漂浮背景效果的制作方法
GIF動圖效果不是很好,實(shí)際效果非常平滑very smooth,而且添加不同的圖形可以組成各種效果,目前已經(jīng)用在我們項(xiàng)目的注冊界面~

原理:
實(shí)現(xiàn)原理很簡單,每一個(gè)懸浮的“小物體”就是一個(gè)自定義View,這些小的自定義View都盛放在一個(gè)自定義的ViewGroup中。然后所有的視圖都放在這個(gè)ViewGroup之上,這樣就相當(dāng)于做一個(gè)可動的背景。
下面結(jié)合代碼詳細(xì)介紹下:
詳解:
FloatObject
懸浮的物體,繼承自View,需要重寫onDraw方法,主要作用就是來畫出自己,并進(jìn)行隨機(jī)曲線運(yùn)動。
任何需要畫出的對象都需要繼承FloatObject,并重寫提供的drawFloatObject方法,在此方法中可以通過設(shè)置畫筆和畫布畫出任意圖形。比如下面是畫出一行文字:
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);
}
}
隨機(jī)曲線:
其實(shí)最復(fù)雜的部分就是讓漂浮的物體做隨機(jī)無規(guī)則的曲線運(yùn)動,并且每個(gè)漂浮物的速度不同,這樣整個(gè)漂浮動畫才更加自然。
我之前想過使用布朗運(yùn)動,但是在網(wǎng)上找了好久也沒找到一個(gè)好用的算法。
最后只能還是使用3點(diǎn)賽貝爾曲線,使漂浮物沿著一條賽貝爾曲線運(yùn)動,達(dá)到終點(diǎn)時(shí),再隨機(jī)產(chǎn)生一條新的曲線,這樣就可以實(shí)現(xiàn)隨機(jī)曲線運(yùn)動了。
控制運(yùn)動的代碼如下:
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:
// 更新賽貝爾曲線點(diǎn)
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
}
// 計(jì)算塞貝兒曲線的當(dāng)前點(diǎn)
PointF bezierPoint = CalculateBezierPoint(mCurDistance / distance, start, c1, c2, end);
x = bezierPoint.x;
y = bezierPoint.y;
// 更新當(dāng)前路徑
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);
}
}
關(guān)于賽貝爾曲線運(yùn)動的算法都是復(fù)用之前寫的一篇文章ANDROID模擬火花粒子的滑動噴射效果,如果大家有興趣可以看看。
FloatBackground
FloatBackground繼承自FrameLayout,里面有一個(gè)用于存放FloatObject的集合。
FloatBackground的主要作用就是繪制所有的“漂浮物”,以及維護(hù)其生命周期:
初始化:
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);
}
// 隔一段時(shí)間重繪一次, 動畫效果
getHandler().postDelayed(runnable, DELAY);
}
// 重繪線程
private Runnable runnable = new Runnable() {
@Override
public void run() {
invalidate();
// 控制幀數(shù)
}
};
開始和結(jié)束:
public void startFloat() {
for (FloatObject floatObject : floats) {
floatObject.setStatus(FloatObject.START);
}
}
public void endFloat() {
for (FloatObject floatObject : floats) {
floatObject.setStatus(FloatObject.END);
}
}
使用
使用時(shí)非常簡單,在layout文件中將FloatBackground設(shè)置為最底層的視圖(其實(shí)就是當(dāng)作一個(gè)背景):
<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>
在代碼中進(jìn)行如下調(diào)用:
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));
浮物”時(shí):floatBackground.addFloatView(new FloatText( 0.3f, 0.6f, “E”))
接收的三個(gè)參數(shù)分別為出生位置在屏幕寬的百分比,長的百分比,和顯示的文字。
Github
https://github.com/a396901990/FloatBackground
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android TextView設(shè)置背景色與邊框的方法詳解
- Android ListView的item背景色設(shè)置和item點(diǎn)擊無響應(yīng)的解決方法
- Android selector背景選擇器的使用詳解
- android 自定義ScrollView實(shí)現(xiàn)背景圖片伸縮的實(shí)現(xiàn)代碼及思路
- android實(shí)現(xiàn)背景平鋪的三種方法
- Android實(shí)現(xiàn)沉浸式通知欄通知欄背景顏色跟隨app導(dǎo)航欄背景顏色而改變
- Android編程實(shí)現(xiàn)popupwindow彈出后屏幕背景變成半透明效果
- android中實(shí)現(xiàn)背景圖片顏色漸變方法
- Android編程簡單實(shí)現(xiàn)ImageView點(diǎn)擊時(shí)背景圖修改的方法
- Android中實(shí)現(xiàn)布局背景模糊化處理的方法
相關(guān)文章
Android 監(jiān)聽屏幕是否鎖屏的實(shí)例代碼
今天小編通過本文給大家分享android如何監(jiān)聽手機(jī)屏幕是否鎖屏。實(shí)現(xiàn)方法很簡單,需要的朋友參考下吧2017-09-09
Android網(wǎng)頁H5 Input選擇相機(jī)和系統(tǒng)相冊
這篇文章主要為大家詳細(xì)介紹了Android網(wǎng)頁H5 Input選擇相機(jī)和系統(tǒng)相冊,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-10-10
Android WebView實(shí)現(xiàn)頂部進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了Android WebView實(shí)現(xiàn)頂部進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
Android程序開發(fā)ListView+Json+異步網(wǎng)絡(luò)圖片加載+滾動翻頁的例子(圖片能緩存,圖片不錯(cuò)亂)
這篇文章主要介紹了Android程序開發(fā)ListView+Json+異步網(wǎng)絡(luò)圖片加載+滾動翻頁的例子(圖片能緩存,圖片不錯(cuò)亂) 的相關(guān)資料,需要的朋友可以參考下2016-01-01
Android編程實(shí)現(xiàn)webview將網(wǎng)頁打包成apk的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)webview將網(wǎng)頁打包成apk的方法,以打包HTML5為例分析了webview打包apk的相關(guān)方法、屬性與事件操作技巧,需要的朋友可以參考下2017-08-08

