最終靜態(tài)效果
最終動(dòng)態(tài)效果
Flash素材來(lái)自http://sc.chinaz.com/微服,自己通過(guò)一些工具提取成圖片栈妆。
涉及的知識(shí)點(diǎn)
-
幀動(dòng)畫(huà)(Frame Animation)
這個(gè)Demo有兩個(gè)幀動(dòng)畫(huà)叉信,分別是自行車(chē)跳躍和自行車(chē)騎行中(輪胎滾動(dòng)狀態(tài))時(shí)的幀動(dòng)畫(huà)。代碼如下:
自行車(chē)跳躍:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@mipmap/jump_0" android:duration="50" />
<item android:drawable="@mipmap/jump_1" android:duration="50" />
<item android:drawable="@mipmap/jump_2" android:duration="50" />
<item android:drawable="@mipmap/jump_3" android:duration="50" />
<item android:drawable="@mipmap/jump_4" android:duration="50" />
<item android:drawable="@mipmap/jump_5" android:duration="50" />
<item android:drawable="@mipmap/jump_6" android:duration="50" />
<item android:drawable="@mipmap/jump_7" android:duration="50" />
<item android:drawable="@mipmap/jump_8" android:duration="50" />
<item android:drawable="@mipmap/jump_9" android:duration="50" />
<item android:drawable="@mipmap/jump_10" android:duration="50" />
<item android:drawable="@mipmap/jump_11" android:duration="50" />
<item android:drawable="@mipmap/jump_12" android:duration="50" />
<item android:drawable="@mipmap/jump_13" android:duration="50" />
<item android:drawable="@mipmap/jump_14" android:duration="50" />
<item android:drawable="@mipmap/jump_15" android:duration="50" />
<item android:drawable="@mipmap/jump_16" android:duration="50" />
<item android:drawable="@mipmap/jump_17" android:duration="50" />
<item android:drawable="@mipmap/jump_18" android:duration="50" />
<item android:drawable="@mipmap/jump_19" android:duration="50" />
<item android:drawable="@mipmap/jump_20" android:duration="50" />
</animation-list>
自行車(chē)輪子滾動(dòng):
<?xml version="1.0" encoding="utf-8"?>
<animation-list
android:oneshot="false"
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@mipmap/riding_0" android:duration="50"/>
<item android:drawable="@mipmap/riding_1" android:duration="50"/>
<item android:drawable="@mipmap/riding_2" android:duration="50"/>
<item android:drawable="@mipmap/riding_3" android:duration="50"/>
<item android:drawable="@mipmap/riding_4" android:duration="50"/>
<item android:drawable="@mipmap/riding_5" android:duration="50"/>
<item android:drawable="@mipmap/riding_6" android:duration="50"/>
<item android:drawable="@mipmap/riding_7" android:duration="50"/>
<item android:drawable="@mipmap/riding_8" android:duration="50"/>
<item android:drawable="@mipmap/riding_9" android:duration="50"/>
<item android:drawable="@mipmap/riding_10" android:duration="50"/>
<item android:drawable="@mipmap/riding_11" android:duration="50"/>
<item android:drawable="@mipmap/riding_12" android:duration="50"/>
<item android:drawable="@mipmap/riding_13" android:duration="50"/>
<item android:drawable="@mipmap/riding_14" android:duration="50"/>
</animation-list>
保存成xml存在drawable文件夾中琼富,之后就可以當(dāng)drawable對(duì)象一樣設(shè)置到imageview中了
android:oneshot
設(shè)置動(dòng)畫(huà)是否只運(yùn)行一次
android:drawable
設(shè)置當(dāng)前幀的圖片
android:duration
設(shè)置當(dāng)前幀的播放時(shí)長(zhǎng)雌贱,單位ms
調(diào)用方式:
package com.hellsam.drawableanimatordemo;
import android.animation.ValueAnimator;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
private ImageView mIV;
private AnimationDrawable mAnimationDrawable;
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mIV = (ImageView) findViewById(R.id.iv_canvas);
getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
mIV.setBackgroundResource(R.drawable.riding);
mAnimationDrawable = (AnimationDrawable) mIV.getBackground();
mAnimationDrawable.start();
}
});
}
});
}
}
-
屬性動(dòng)畫(huà)(Property Animation)
這個(gè)demo中自行車(chē)左右移動(dòng)是用屬性動(dòng)畫(huà)實(shí)現(xiàn)的。代碼如下:
mIV.animate().translationXBy(10000).setInterpolator(new LinearInterpolator()).setDuration(20000).start();
這里的10000只是為了大于屏幕寬度死遭,使按下按鈕后(未抬起)車(chē)子能一直移動(dòng)超過(guò)一個(gè)屏幕寬度广恢。
20000是根據(jù)車(chē)子的速度和10000設(shè)置的。
這里用線性差值器(LinearInterpolator)是小車(chē)勻速運(yùn)動(dòng)呀潭。
下面給出其余相關(guān)代碼
MainActivity:
package com.hellsam.drawableanimatordemo;
import android.animation.ValueAnimator;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity implements ValueAnimator.AnimatorUpdateListener {
private ImageView mIV;
private AnimationDrawable mAnimationDrawable;
private Button mLeftBtn;
private Button mRightBtn;
private Button mJumpBtn;
private Handler mHandler = new Handler();
//是否正在往左運(yùn)動(dòng)钉迷,是否正在往右運(yùn)動(dòng),是否正在跳躍
private boolean isRidingLeft = false, isRidingRight = false, isJumping = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mIV = (ImageView) findViewById(R.id.iv_canvas);
mLeftBtn = (Button) findViewById(R.id.btn_left);
mRightBtn = (Button) findViewById(R.id.btn_right);
mJumpBtn = (Button) findViewById(R.id.btn_jump);
getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
//先加載一下幀動(dòng)畫(huà)資源钠署,避免第一次加載的時(shí)候的卡頓
mIV.setBackgroundResource(R.drawable.riding);
mAnimationDrawable = (AnimationDrawable) mIV.getBackground();
mIV.setBackgroundResource(R.drawable.jump);
mAnimationDrawable = (AnimationDrawable) mIV.getBackground();
mIV.setBackgroundResource(R.mipmap.riding_0);
}
});
}
});
mJumpBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
jump();
}
});
mRightBtn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!isJumping) {
ride();
}
isRidingRight = true;
isRidingLeft = false;
ride2Right();
break;
case MotionEvent.ACTION_UP:
if (!isRidingLeft) {
mIV.animate().cancel();
}
if (!isJumping && !isRidingLeft) {
mAnimationDrawable.stop();
}
isRidingRight = false;
break;
}
return false;
}
});
mLeftBtn.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!isJumping) {
ride();
}
isRidingLeft = true;
isRidingRight = false;
ride2Left();
break;
case MotionEvent.ACTION_UP:
if (!isRidingRight) {
mIV.animate().cancel();
}
if (!isJumping && !isRidingRight) {
mAnimationDrawable.stop();
}
isRidingLeft = false;
break;
}
return false;
}
});
}
/**
* 判斷車(chē)子是否在運(yùn)動(dòng)
* @return
*/
private boolean isRiding() {
return isRidingLeft || isRidingRight;
}
/**
* 播放騎行中(車(chē)輪滾動(dòng)狀態(tài))的幀動(dòng)畫(huà)
*/
private void ride() {
mIV.setBackgroundResource(R.drawable.riding);
mAnimationDrawable = (AnimationDrawable) mIV.getBackground();
if (mAnimationDrawable != null && !mAnimationDrawable.isRunning()) {
mAnimationDrawable.start();
}
}
/**
* 播放跳躍的幀動(dòng)畫(huà)
*/
private void jump() {
mIV.setBackgroundResource(R.drawable.jump);
mAnimationDrawable = (AnimationDrawable) mIV.getBackground();
if (mAnimationDrawable != null && !mAnimationDrawable.isRunning()) {
mAnimationDrawable.stop();
mAnimationDrawable.start();
isJumping = true;
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mAnimationDrawable.stop();
isJumping = false;
if (isRiding()) {
ride();
}
}
}, 21 * 50);
}
}
/**
* 往右運(yùn)動(dòng)
*/
private void ride2Right() {
mIV.animate().cancel();
mIV.animate().translationXBy(10000).setInterpolator(new LinearInterpolator()).setDuration(20000).start();
mIV.animate().setUpdateListener(MainActivity.this);
}
/**
* 往左運(yùn)動(dòng)
*/
private void ride2Left() {
mIV.animate().cancel();
mIV.animate().translationXBy(-10000).setInterpolator(new LinearInterpolator()).setDuration(20000).start();
mIV.animate().setUpdateListener(MainActivity.this);
}
/**
* 當(dāng)自行車(chē)出了屏幕邊界后糠聪,重新從另一面駛?cè)? * @param animation
*/
@Override
public void onAnimationUpdate(ValueAnimator animation) {
if (mIV.getTranslationX() > getWindow().getDecorView().getWidth() - 34) {
mIV.setTranslationX(-mIV.getWidth() + 70);
ride2Right();
} else if (mIV.getTranslationX() < -mIV.getWidth() + 70) {
mIV.setTranslationX(getWindow().getDecorView().getWidth() - 34);
ride2Left();
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" tools:context=".MainActivity"
android:background="#FFF">
<ImageView
android:id="@+id/iv_canvas"
android:layout_width="150dp"
android:layout_height="150dp"/>
<LinearLayout
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:orientation="horizontal">
<Button
android:id="@+id/btn_left"
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Left"/>
<Button
android:id="@+id/btn_right"
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Right"/>
<Button
android:id="@+id/btn_jump"
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Jump"/>
</LinearLayout>
</RelativeLayout>
全部代碼下載地址:
https://github.com/hellsam/DrawableAnimationDemo
<strong>歡迎留言交流,如有描述不當(dāng)或錯(cuò)誤的地方還請(qǐng)留言告知</strong>