Android自定義View實(shí)現(xiàn)多片葉子旋轉(zhuǎn)滑動(dòng)(五)
上一篇《Android 自定義View(四) 葉子飄動(dòng)+旋轉(zhuǎn)效果》實(shí)現(xiàn)了單片葉子的滑動(dòng)及旋轉(zhuǎn),下面實(shí)現(xiàn)多片葉子的滑動(dòng)旋轉(zhuǎn)功能

實(shí)現(xiàn)思路比較簡(jiǎn)單,就是添加一個(gè)葉子Leaf類,儲(chǔ)存每片葉子的信息,
然后隨機(jī)產(chǎn)生葉子的坐標(biāo)及旋轉(zhuǎn)角度,最后實(shí)時(shí)獲取每片葉子信息,添加到畫(huà)布中
1、Leaf.java 葉子類
private class Leaf {
// 葉子的坐標(biāo)
float x, y;
// 旋轉(zhuǎn)角度
int rotateAngle;
// 起始時(shí)間(ms)
long startTime;
}
2、初始化每片葉子的信息,然后保存到list中
//使葉子初始時(shí)間有間隔
int addTime;
private Leaf getLeaf() {
Random random = new Random();
Leaf leaf = new Leaf();
//隨機(jī)初始化葉子初始角度
leaf.rotateAngle = random.nextInt(360);
//隨機(jī)初始化葉子啟動(dòng)時(shí)間
addTime += random.nextInt((int) (cycleTime));
leaf.startTime = System.currentTimeMillis() + cycleTime + addTime;
return leaf;
}
private List<Leaf> getLeafs(int leafSize) {
List<Leaf> list = new LinkedList<Leaf>();
for (int i=0; i<leafSize; i++) {
list.add(getLeaf());
}
return list;
}
3、接下去就是改寫(xiě)getLocation()及getRotate()方法,使其返回每片葉子的坐標(biāo)及旋轉(zhuǎn)角度
//獲取每片葉子在XY軸上的滑動(dòng)值
private void getLocation(Leaf leaf) {
float betweenTime = leaf.startTime - System.currentTimeMillis();
//周期結(jié)束再加一個(gè)cycleTime
if(betweenTime < 0) {
leaf.startTime = System.currentTimeMillis() + cycleTime + new Random().nextInt((int) (cycleTime));
betweenTime = cycleTime;
}
//通過(guò)時(shí)間差計(jì)算出葉子的坐標(biāo)
float fraction = (float) betweenTime / cycleTime;
float x = (int)(width * fraction);
leaf.x = x;
float w = (float) ((float) 2 * Math.PI / width);
int y = (int) (18 * Math.sin(w * x)) + (height-mLeafHeight)/2;
leaf.y = y;
}
//獲取每片葉子的旋轉(zhuǎn)角度
private void getRotate(Leaf leaf) {
float scale = ((leaf.startTime - System.currentTimeMillis())%cycleTime)/ (float)cycleTime;
int rotate = (int)(scale * 360);
leaf.rotateAngle = rotate;
}
4、在onDraw()方法中,畫(huà)出每片葉子
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//畫(huà)葉子
int size = leafList.size();
for (int i=0; i<size; i++) {
Leaf leaf = leafList.get(i);
//獲取葉子坐標(biāo)
getLocation(leaf);
//獲取葉子旋轉(zhuǎn)角度
getRotate(leaf);
canvas.save();
Matrix matrix = new Matrix();
//設(shè)置滑動(dòng)
matrix.postTranslate(leaf.x, leaf.y);
//設(shè)置旋轉(zhuǎn)
matrix.postRotate(leaf.rotateAngle, leaf.x + mLeafWidth / 2, leaf.y + mLeafHeight / 2);
//添加葉子到畫(huà)布
canvas.drawBitmap(mLeafBitmap, matrix, new Paint());
canvas.restore();
}
//調(diào)用onDraw()重復(fù)滑動(dòng)
postInvalidate();
}
完整代碼:
public class LeafView extends View {
private String TAG = "--------LeafView";
private Resources mResources;
//背景圖、葉子
private Bitmap mLeafBitmap, bgBitmap;
//整個(gè)控件的寬度和高度
private int width, height;
private Paint bgPaint;
private RectF bgRect;
private Rect bgDestRect;
//存放葉子lsit
private List<Leaf> leafList;
//葉子的寬和高
private int mLeafWidth, mLeafHeight;
//葉子滑動(dòng)一周的時(shí)間5秒
private final static long cycleTime = 5000;
//葉子數(shù)量
private final static int leafNumber = 5;
public LeafView(Context context, AttributeSet attrs) {
super(context, attrs);
mResources = getResources();
mLeafBitmap = ((BitmapDrawable) mResources.getDrawable(R.drawable.leaf, null)).getBitmap();
mLeafWidth = mLeafBitmap.getWidth();
mLeafHeight = mLeafBitmap.getHeight()
bgBitmap = ((BitmapDrawable) mResources.getDrawable(R.drawable.leaf_kuang, null)).getBitmap();
bgPaint = new Paint();
bgPaint.setColor(mResources.getColor(R.color.bg_color));
//獲取所有葉子的信息,放入list
leafList = getLeafs(leafNumber);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width = w;
height = h;
bgDestRect = new Rect(0, 0 , width, height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
bgRect = new RectF(0, 0 , width, height);
//畫(huà)背景顏色到畫(huà)布
canvas.drawRect(bgRect, bgPaint);
//畫(huà)背景圖片到畫(huà)布
canvas.drawBitmap(bgBitmap, null, bgDestRect, null);
//畫(huà)葉子
int size = leafList.size();
for (int i=0; i<size; i++) {
Leaf leaf = leafList.get(i);
//獲取葉子坐標(biāo)
getLocation(leaf);
//獲取葉子旋轉(zhuǎn)角度
getRotate(leaf);
canvas.save();
Matrix matrix = new Matrix();
//設(shè)置滑動(dòng)
matrix.postTranslate(leaf.x, leaf.y);
//設(shè)置旋轉(zhuǎn)
matrix.postRotate(leaf.rotateAngle, leaf.x + mLeafWidth / 2, leaf.y + mLeafHeight / 2);
//添加葉子到畫(huà)布
canvas.drawBitmap(mLeafBitmap, matrix, new Paint());
canvas.restore();
}
//調(diào)用onDraw()重復(fù)滑動(dòng)
postInvalidate();
}
//獲取每片葉子在XY軸上的滑動(dòng)值
private void getLocation(Leaf leaf) {
float betweenTime = leaf.startTime - System.currentTimeMillis();
//周期結(jié)束再加一個(gè)cycleTime
if(betweenTime < 0) {
leaf.startTime = System.currentTimeMillis() + cycleTime + new Random().nextInt((int) (cycleTime));
betweenTime = cycleTime;
}
//通過(guò)時(shí)間差計(jì)算出葉子的坐標(biāo)
float fraction = (float) betweenTime / cycleTime;
float x = (int)(width * fraction);
leaf.x = x;
float w = (float) ((float) 2 * Math.PI / width);
int y = (int) (18 * Math.sin(w * x)) + (height-mLeafHeight)/2;
leaf.y = y;
}
//獲取每片葉子的旋轉(zhuǎn)角度
private void getRotate(Leaf leaf) {
float scale = ((leaf.startTime - System.currentTimeMillis())%cycleTime)/ (float)cycleTime;
int rotate = (int)(scale * 360);
leaf.rotateAngle = rotate;
}
private class Leaf {
// 葉子的坐標(biāo)
float x, y;
// 旋轉(zhuǎn)角度
int rotateAngle;
// 起始時(shí)間(ms)
long startTime;
}
private List<Leaf> getLeafs(int leafSize) {
List<Leaf> list = new LinkedList<Leaf>();
for (int i=0; i<leafSize; i++) {
list.add(getLeaf());
}
return list;
}
//使葉子初始時(shí)間有間隔
int addTime;
private Leaf getLeaf() {
Random random = new Random();
Leaf leaf = new Leaf();
leaf.rotateAngle = random.nextInt(360);
addTime += random.nextInt((int) (cycleTime));
leaf.startTime = System.currentTimeMillis() + cycleTime + addTime;
return leaf;
}
}
這里還有很多瑕疵,比如葉子的滑動(dòng)范圍覆蓋了邊框等等
需要圖片等信息的可以從下面的Github地址下載,不過(guò)原文比較復(fù)雜
參考 https://github.com/Ajian-studio/GALeafLoading
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- android中Bitmap用法(顯示,保存,縮放,旋轉(zhuǎn))實(shí)例分析
- Android使用Matrix旋轉(zhuǎn)圖片模擬碟片加載過(guò)程
- Android自定義View實(shí)現(xiàn)葉子飄動(dòng)旋轉(zhuǎn)效果(四)
- Android中利用matrix 控制圖片的旋轉(zhuǎn)、縮放、移動(dòng)
- Android 圖片縮放與旋轉(zhuǎn)的實(shí)現(xiàn)詳解
- Android UI之ImageView實(shí)現(xiàn)圖片旋轉(zhuǎn)和縮放
- Android實(shí)現(xiàn)圖片反轉(zhuǎn)、翻轉(zhuǎn)、旋轉(zhuǎn)、放大和縮小
- 基于Android 實(shí)現(xiàn)圖片平移、縮放、旋轉(zhuǎn)同時(shí)進(jìn)行
- Android實(shí)現(xiàn)旋轉(zhuǎn),放大,縮小圖片的方法
- Android實(shí)現(xiàn)Bitmap位圖旋轉(zhuǎn)效果
相關(guān)文章
Android簡(jiǎn)單實(shí)現(xiàn)自定義彈框(PopupWindow)
本文主要介紹了Android利用PopupWindow實(shí)現(xiàn)自定義彈框的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-04-04
Android編程實(shí)現(xiàn)抽屜效果的方法詳解
這篇文章主要介紹了Android編程實(shí)現(xiàn)抽屜效果的方法,結(jié)合具體實(shí)例形式分析了Android實(shí)現(xiàn)抽屜效果的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-05-05
Android自定義View實(shí)現(xiàn)抖音飄動(dòng)紅心效果
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)抖音飄動(dòng)紅心效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05
Android 藍(lán)牙連接 ESC/POS 熱敏打印機(jī)打印實(shí)例(ESC/POS指令篇)
這篇文章主要介紹了Android 藍(lán)牙連接 ESC/POS 熱敏打印機(jī)打印實(shí)例(ESC/POS指令篇),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04
Android自定義控件實(shí)現(xiàn)icon+文字的多種效果
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)icon+文字的多種效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
Android編程實(shí)現(xiàn)從字符串中查找電話號(hào)碼的方法
這篇文章主要介紹了Android編程實(shí)現(xiàn)從字符串中查找電話號(hào)碼的方法,涉及Android針對(duì)字符串的匹配與查找相關(guān)技巧,需要的朋友可以參考下2016-03-03
Android使用vitamio插件實(shí)現(xiàn)視頻播放器
這篇文章主要為大家詳細(xì)介紹了Android使用vitamio實(shí)現(xiàn)視頻播放器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04
Android使用表格布局設(shè)計(jì)注冊(cè)界面
這篇文章主要為大家詳細(xì)介紹了Android使用表格布局設(shè)計(jì)注冊(cè)界面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
Java操作FreeMarker模板引擎的基本用法示例小結(jié)
這篇文章主要介紹了Java操作FreeMarker模板引擎的基本用法示例小結(jié),FreeMarker本身由Java寫(xiě)成,用模板來(lái)生成文本輸出,需要的朋友可以參考下2016-02-02

