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

實(shí)現(xiàn)思路比較簡單,就是添加一個(gè)葉子Leaf類,儲(chǔ)存每片葉子的信息,
然后隨機(jī)產(chǎn)生葉子的坐標(biāo)及旋轉(zhuǎn)角度,最后實(shí)時(shí)獲取每片葉子信息,添加到畫布中
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、接下去就是改寫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; } //通過時(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()方法中,畫出每片葉子
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //畫葉子 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); //添加葉子到畫布 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); //畫背景顏色到畫布 canvas.drawRect(bgRect, bgPaint); //畫背景圖片到畫布 canvas.drawBitmap(bgBitmap, null, bgDestRect, null); //畫葉子 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); //添加葉子到畫布 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; } //通過時(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地址下載,不過原文比較復(fù)雜
參考 https://github.com/Ajian-studio/GALeafLoading
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注