Android實(shí)現(xiàn)花瓣飄落效果的步驟
效果展示

實(shí)現(xiàn)原理
- 首先需要生成繪制小花的坐標(biāo)點(diǎn),坐標(biāo)點(diǎn)的橫坐標(biāo)是根據(jù)控件的寬度隨機(jī)生成的,而縱坐標(biāo)則設(shè)置為小花圖片高度的負(fù)值(這樣可以實(shí)現(xiàn)小花從屏幕外進(jìn)入)。
- 將這些點(diǎn)存儲(chǔ)到集合當(dāng)中。
- 遍歷集合根據(jù)點(diǎn)的位置繪制小花
- 繪制完后不斷增加各個(gè)點(diǎn)的縱坐標(biāo)
實(shí)現(xiàn)步驟
1.定義變量將變量初始化
private SurfaceHolder mHolder;
private boolean mFlag = true;//繪制小花線程的開關(guān)標(biāo)志
private ArrayList<PointF> mFlowers;//小花點(diǎn)的坐標(biāo)集合
private Random mRandom;//負(fù)責(zé)隨機(jī)數(shù)生成
private Bitmap mBitmap;//小花的圖案
public FlowerView(Context context) {
super(context);
init();
}
public FlowerView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public FlowerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
mHolder = getHolder();
mHolder.addCallback(this);
//設(shè)置背景透明
this.setZOrderOnTop(true);
mHolder.setFormat(PixelFormat.TRANSLUCENT);
mFlowers = new ArrayList<>();
mRandom = new Random();
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_hua);
}
2.實(shí)現(xiàn)添加花朵坐標(biāo)點(diǎn)的方法
/**
* 添加花朵
*/
private void addFlower(){
PointF point = new PointF();
point.x=mRandom.nextInt(getWidth());//根據(jù)控件寬度隨機(jī)生成X軸坐標(biāo)
point.y=-mBitmap.getHeight();//縱坐標(biāo)設(shè)置為小花圖像的負(fù)值(產(chǎn)生從屏幕外進(jìn)入的效果)
mFlowers.add(point);//將坐標(biāo)點(diǎn)添加進(jìn)集合
}
3.實(shí)現(xiàn)SurfaceHolder.Callback及Runnable接口
public class FlowerView extends SurfaceView implements SurfaceHolder.Callback,Runnable
4.在run方法中實(shí)現(xiàn)繪制邏輯
@Override
public void run() {
while (mFlag){
try {
Thread.sleep(80);//控制小花的下落速度
Canvas canvas = mHolder.lockCanvas();
PointF pointF = null;
//清屏操作(否則會(huì)殘留一些無用圖像)
if(canvas!=null){
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
}else {
continue;
}
for(PointF point: mFlowers){
pointF = point;
canvas.drawBitmap(mBitmap,pointF.x,pointF.y,null);
int i = mRandom.nextInt(getHeight()/50)+getHeight()/50;//修改雨滴線的縱坐標(biāo),使其看起來在下雨
pointF.y=pointF.y+i;
}
mHolder.unlockCanvasAndPost(canvas);
addFlower();
//當(dāng)繪制點(diǎn)的縱坐標(biāo)大于控件高度時(shí),將該點(diǎn)移除
if(mFlowers.size()>0&&pointF!=null&&pointF.y>=getHeight()){
mFlowers.remove(pointF);
}
}catch (Exception e){}
}
}
5.在SurfaceHolder.Callback的回調(diào)方法中開啟繪制線程
@Override
public void surfaceCreated(SurfaceHolder holder) {
mFlag = true;//surface創(chuàng)建時(shí)將線程開關(guān)打開
new Thread(this).start();//開啟線程繪制
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mFlowers.clear();//當(dāng)控件發(fā)生改變時(shí)清除之前的繪制點(diǎn)
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mFlag = false;//當(dāng)surface銷毀時(shí)關(guān)掉繪制線程
}
完整代碼展示
public class FlowerView extends SurfaceView implements SurfaceHolder.Callback,Runnable{
private SurfaceHolder mHolder;
private boolean mFlag = true;//繪制小花線程的開關(guān)標(biāo)志
private ArrayList<PointF> mFlowers;//小花點(diǎn)的坐標(biāo)集合
private Random mRandom;//負(fù)責(zé)隨機(jī)數(shù)生成
private Bitmap mBitmap;//小花的圖案
public FlowerView(Context context) {
super(context);
init();
}
public FlowerView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public FlowerView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
mHolder = getHolder();
mHolder.addCallback(this);
//設(shè)置背景透明
this.setZOrderOnTop(true);
mHolder.setFormat(PixelFormat.TRANSLUCENT);
mFlowers = new ArrayList<>();
mRandom = new Random();
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_hua);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mFlag = true;
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mFlowers.clear();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mFlag = false;
}
@Override
public void run() {
while (mFlag){
try {
Thread.sleep(80);
Canvas canvas = mHolder.lockCanvas();
PointF pointF = null;
//清屏操作
if(canvas!=null){
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
}else {
continue;
}
for(PointF point: mFlowers){
pointF = point;
canvas.drawBitmap(mBitmap,pointF.x,pointF.y,null);
int i = mRandom.nextInt(getHeight()/50)+getHeight()/50;//修改雨滴線的縱坐標(biāo),使其看起來在下雨
pointF.y=pointF.y+i;
}
mHolder.unlockCanvasAndPost(canvas);
addFlower();
if(mFlowers.size()>0&&pointF!=null&&pointF.y>=getHeight()){
mFlowers.remove(pointF);
}
}catch (Exception e){}
}
}
/**
* 添加花朵
*/
private void addFlower(){
PointF point = new PointF();
point.x=mRandom.nextInt(getWidth());
point.y=-mBitmap.getHeight();
mFlowers.add(point);
}
}
以上就是Android實(shí)現(xiàn)花瓣飄落效果的步驟的詳細(xì)內(nèi)容,更多關(guān)于Android實(shí)現(xiàn)花瓣飄落效果的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- android仿微信表情雨下落效果的實(shí)現(xiàn)方法
- Android開發(fā)之多線程中實(shí)現(xiàn)利用自定義控件繪制小球并完成小球自動(dòng)下落功能實(shí)例
- Android實(shí)現(xiàn)啟動(dòng)頁倒計(jì)時(shí)效果
- Android自定義圓形進(jìn)度條效果
- Android使用ViewPager實(shí)現(xiàn)啟動(dòng)引導(dǎo)頁效果
- Android實(shí)現(xiàn)平滑翻動(dòng)效果
- Android如何用自定義View實(shí)現(xiàn)雪花效果
- Android實(shí)現(xiàn)仿微軟系統(tǒng)加載動(dòng)畫效果
- android實(shí)現(xiàn)音樂跳動(dòng)效果的示例代碼
- Android實(shí)現(xiàn)三角形氣泡效果方式匯總
相關(guān)文章
Android 中 SwipeLayout一個(gè)展示條目底層菜單的側(cè)滑控件源碼解析
這篇文章主要介紹了Android 中 SwipeLayout一個(gè)展示條目底層菜單的側(cè)滑控件源碼解析,需要的朋友可以參考下2016-12-12
Android編程簡(jiǎn)單實(shí)現(xiàn)九宮格示例
這篇文章主要介紹了Android編程簡(jiǎn)單實(shí)現(xiàn)九宮格,結(jié)合具體實(shí)例形式分析了Android實(shí)現(xiàn)九宮格的具體步驟與相關(guān)布局、功能實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-06-06
Android Activity的生命周期與加載模式超詳細(xì)圖文解析
這篇文章主要介紹了Android Activity的生命周期與加載模式,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02
Android開發(fā)技巧之在a標(biāo)簽或TextView控件中單擊鏈接彈出Activity(自定義動(dòng)作)
a標(biāo)簽以及TextView自動(dòng)識(shí)別的特殊文本(網(wǎng)址、電話號(hào)、Email等),這些都可以通過單擊來觸發(fā)不同的動(dòng)作;但如果讀者想在單擊鏈接時(shí)執(zhí)行任意自定義的動(dòng)作,那么將要介紹的一定是你想要的了2013-01-01
Android?Flutter實(shí)現(xiàn)精靈圖的使用詳解
在游戲開發(fā)中,精靈圖會(huì)將一個(gè)人物所有動(dòng)作放置在一張圖片中,通過坐標(biāo)定位選取其中一張圖展示。本文就來教你如何使用精靈圖,感興趣的可以了解一下2022-08-08
Android自定義密碼輸入框的簡(jiǎn)單實(shí)現(xiàn)過程
在最近的項(xiàng)目中,用戶需要輸入密碼,不想用系統(tǒng)鍵盤,就寫了一個(gè)自定義鍵盤,下面這篇文章主要給大家介紹了關(guān)于Android自定義密碼輸入框的簡(jiǎn)單實(shí)現(xiàn)過程,需要的朋友可以參考下2021-11-11
Android 通過jni返回Mat數(shù)據(jù)類型方法
今天小編就為大家分享一篇Android 通過jni返回Mat數(shù)據(jù)類型方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-08-08
Android編程之PopupWindow隱藏及顯示方法示例(showAtLocation,showAsDropDown
這篇文章主要介紹了Android編程之PopupWindow隱藏及顯示方法,結(jié)合實(shí)例形式分析了showAtLocation及showAsDropDown方法實(shí)現(xiàn)PopupWindow控件隱藏及顯示功能相關(guān)操作技巧,需要的朋友可以參考下2017-02-02

