android仿騰訊小火箭案例
阿新 • • 發佈:2019-02-14
效果展示
思路分析
- 首先要準備兩張小火箭圖片,通過幀動畫來實現火箭噴火的效果
- 準備兩張看似冒白煙的圖片,在火箭的發射的時候通過漸變動畫實現發射時的效果
- 熟悉view的onTouch事件處理,以及android基本動畫的使用
- 當小火箭被拖動到發射區域時擡起時火箭發射,執行冒白煙的漸變動畫,當火箭飛出螢幕時結束所有動畫
具體實現步驟
一、在res/drawable目錄下建立一個幀動畫的xml檔案,desktop_rocket_launch_1和desktop_rocket_launch_1分別是兩張不同的小火箭狀態的圖片
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/selected"
android:oneshot="false" >
<item
android:drawable="@drawable/desktop_rocket_launch_1"
android:duration="50"/>
<item
android:drawable="@drawable/desktop_rocket_launch_2"
android:duration="50"/>
</animation-list>
二、在java檔案中通過下面程式碼的實現小火箭的噴火效果
mImgAnim.setBackgroundResource(R.drawable.desktop_rocket_launch);
AnimationDrawable frameAnimation = (AnimationDrawable) mImgAnim
.getBackground();
frameAnimation.start();
三、觸控小火箭時隨手指移動
mImgAnim.setOnTouchListener(new OnTouchListener() {
private int startX;
private int startY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = (int) event.getRawX();
startY = (int) event.getRawY();
System.out.println("按下");
break;
case MotionEvent.ACTION_MOVE:
System.out.println("移動");
// 獲取移動後的位置
int moveX = (int) event.getRawX();
int moveY = (int) event.getRawY();
// 計算偏移量
int vX = moveX - startX;
int vY = moveY - startY;
// 獲取沒有重繪前view離螢幕左邊和上邊的距離
int l = mImgAnim.getLeft();
int t = mImgAnim.getTop();
l += vX;
t += vY;
// 邊界值處理
l = l < 0 ? 0
: (l > mScreeWidth - mImgAnim.getWidth() ? mScreeWidth
- mImgAnim.getWidth()
: l);
t = t < 0 ? 0
: (t > mScreeHeight - mImgAnim.getHeight() ? mScreeHeight
- mImgAnim.getHeight()
: t);
// r和b受到l和t的影響,所以不用做處理
int r = l + mImgAnim.getWidth();
int b = t + mImgAnim.getHeight();
// 重繪view
mImgAnim.layout(l, t, r, b);
// 修改起點座標
startX = moveX;
startY = moveY;
break;
case MotionEvent.ACTION_UP:
int width = mImgAnim.getWidth();
// 發射火箭
// 判斷是否在指定的位置
if (mImgAnim.getLeft() > mScreeWidth / 2 - width
&& mImgAnim.getLeft() < mScreeWidth / 2 + width
&& mImgAnim.getTop() > mScreeHeight
- mImgAnim.getHeight() - 20) {
System.out.println("發射火箭");
sendRocket();
mSmoke.startAnimation(alphaAnimation);
mSmoke_t.startAnimation(alphaAnimation);
}
break;
}
return true;
}
});
四、當手指擡起時如果火箭位於發射位置,則發射火箭,同時取消所有動畫
new Thread() {
public void run() {
do {
SystemClock.sleep(10);
// 執行在ui執行緒操作
runOnUiThread(new Runnable() {
@Override
public void run() {
// 減小控制元件距離螢幕頂部的距離
int top = mImgAnim.getTop() - 8;
// 重新繪製控制元件
mImgAnim.layout(mImgAnim.getLeft(), top,
mImgAnim.getLeft() + mImgAnim.getWidth(),
top + mImgAnim.getHeight());
System.out.println("top=" + top);
}
});
} while (mImgAnim.getBottom() > 0);
// 關閉動畫
runOnUiThread(new Runnable() {
@Override
public void run() {
mSmoke.clearAnimation();
mSmoke_t.clearAnimation();
}
});
};
}.start();
完整程式碼如下,佈局自定義
/**
* @author rongtao
* 小火箭案例
*/
public class MainActivity extends Activity {
private MainActivity mContext;
private ImageView mImgAnim;
private ImageView mSmoke;
private int mScreeWidth;
private int mScreeHeight;
private AlphaAnimation alphaAnimation;
private ImageView mSmoke_t;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
getScreenInfo();
init();
}
/**
* 獲取螢幕寬高
*/
private void getScreenInfo() {
// 獲取手機螢幕資訊
DisplayMetrics outMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
;
mScreeWidth = outMetrics.widthPixels;
mScreeHeight = outMetrics.heightPixels;
}
private void init() {
mImgAnim = (ImageView) findViewById(R.id.img_anim);
mSmoke = (ImageView) findViewById(R.id.img_smoke);
mSmoke_t = (ImageView) findViewById(R.id.img_smoke_t);
loadAnimation();
touchRocket();
}
private void loadAnimation() {
mImgAnim.setBackgroundResource(R.drawable.desktop_rocket_launch);
AnimationDrawable frameAnimation = (AnimationDrawable) mImgAnim
.getBackground();
frameAnimation.start();
alphaAnimation = new AlphaAnimation(0, 1.0f);// 初始化漸變動畫
alphaAnimation.setDuration(2000);
}
private void touchRocket() {
mImgAnim.setOnTouchListener(new OnTouchListener() {
private int startX;
private int startY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = (int) event.getRawX();
startY = (int) event.getRawY();
System.out.println("按下");
break;
case MotionEvent.ACTION_MOVE:
System.out.println("移動");
// 獲取移動後的位置
int moveX = (int) event.getRawX();
int moveY = (int) event.getRawY();
// 計算偏移量
int vX = moveX - startX;
int vY = moveY - startY;
// 獲取沒有重繪前view離螢幕左邊和上邊的距離
int l = mImgAnim.getLeft();
int t = mImgAnim.getTop();
l += vX;
t += vY;
// 邊界值處理
l = l < 0 ? 0
: (l > mScreeWidth - mImgAnim.getWidth() ? mScreeWidth
- mImgAnim.getWidth()
: l);
t = t < 0 ? 0
: (t > mScreeHeight - mImgAnim.getHeight() ? mScreeHeight
- mImgAnim.getHeight()
: t);
// r和b受到l和t的影響,所以不用做處理
int r = l + mImgAnim.getWidth();
int b = t + mImgAnim.getHeight();
// 重繪view
mImgAnim.layout(l, t, r, b);
// 修改起點座標
startX = moveX;
startY = moveY;
break;
case MotionEvent.ACTION_UP:
int width = mImgAnim.getWidth();
// 發射火箭
// 判斷是否在指定的位置
if (mImgAnim.getLeft() > mScreeWidth / 2 - width
&& mImgAnim.getLeft() < mScreeWidth / 2 + width
&& mImgAnim.getTop() > mScreeHeight
- mImgAnim.getHeight() - 20) {
System.out.println("發射火箭");
sendRocket();
mSmoke.startAnimation(alphaAnimation);
mSmoke_t.startAnimation(alphaAnimation);
}
break;
}
return true;
}
});
}
/**
* 傳送火箭效果
*
* 通過減少Top值得方法實現火箭的發射
*/
protected void sendRocket() {
new Thread() {
public void run() {
do {
SystemClock.sleep(10);
// 執行在ui執行緒操作
runOnUiThread(new Runnable() {
@Override
public void run() {
// 減小控制元件距離螢幕頂部的距離
int top = mImgAnim.getTop() - 8;
// 重新繪製控制元件
mImgAnim.layout(mImgAnim.getLeft(), top,
mImgAnim.getLeft() + mImgAnim.getWidth(),
top + mImgAnim.getHeight());
System.out.println("top=" + top);
}
});
} while (mImgAnim.getBottom() > 0);
// 關閉動畫
runOnUiThread(new Runnable() {
@Override
public void run() {
mSmoke.clearAnimation();
mSmoke_t.clearAnimation();
}
});
};
}.start();
}
}
發射火箭可以通過其他的方式實現,有興趣的自己研究。