Android跳躍吧山地車(chē)

最終靜態(tài)效果

最終動(dòng)態(tài)效果

Flash素材來(lái)自http://sc.chinaz.com/微服,自己通過(guò)一些工具提取成圖片栈妆。

涉及的知識(shí)點(diǎn)

  1. 幀動(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();
                        }
                    });
                }
            });
        }
    }
  1. 屬性動(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>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谐鼎,一起剝皮案震驚了整個(gè)濱河市舰蟆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌狸棍,老刑警劉巖身害,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異草戈,居然都是意外死亡塌鸯,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)唐片,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)丙猬,“玉大人,你說(shuō)我怎么就攤上這事费韭〖肭颍” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵揽思,是天一觀的道長(zhǎng)袜腥。 經(jīng)常有香客問(wèn)我,道長(zhǎng)钉汗,這世上最難降的妖魔是什么羹令? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮损痰,結(jié)果婚禮上福侈,老公的妹妹穿的比我還像新娘。我一直安慰自己卢未,他們只是感情好肪凛,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布堰汉。 她就那樣靜靜地躺著,像睡著了一般伟墙。 火紅的嫁衣襯著肌膚如雪翘鸭。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,255評(píng)論 1 308
  • 那天戳葵,我揣著相機(jī)與錄音就乓,去河邊找鬼。 笑死拱烁,一個(gè)胖子當(dāng)著我的面吹牛生蚁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播戏自,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼邦投,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了擅笔?” 一聲冷哼從身側(cè)響起志衣,我...
    開(kāi)封第一講書(shū)人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎剂娄,沒(méi)想到半個(gè)月后蠢涝,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體玄呛,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡阅懦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了徘铝。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耳胎。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖惕它,靈堂內(nèi)的尸體忽然破棺而出怕午,到底是詐尸還是另有隱情,我是刑警寧澤淹魄,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布郁惜,位于F島的核電站,受9級(jí)特大地震影響甲锡,放射性物質(zhì)發(fā)生泄漏兆蕉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一缤沦、第九天 我趴在偏房一處隱蔽的房頂上張望虎韵。 院中可真熱鬧,春花似錦缸废、人聲如沸包蓝。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)测萎。三九已至亡电,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間硅瞧,已是汗流浹背逊抡。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留零酪,地道東北人冒嫡。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像四苇,于是被迫代替她去往敵國(guó)和親孝凌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,282評(píng)論 25 707
  • ¥開(kāi)啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開(kāi)一個(gè)線程月腋,因...
    小菜c閱讀 6,444評(píng)論 0 17
  • 1 背景 不能只分析源碼呀蟀架,分析的同時(shí)也要整理歸納基礎(chǔ)知識(shí),剛好有人微博私信讓全面說(shuō)說(shuō)Android的動(dòng)畫(huà)榆骚,所以今...
    未聞椛洺閱讀 2,716評(píng)論 0 10
  • Android框架提供了兩種類型的動(dòng)畫(huà):View Animation(也稱視圖動(dòng)畫(huà))和Property Anima...
    RxCode閱讀 1,644評(píng)論 1 5
  • 營(yíng)銷是我們突破社會(huì)競(jìng)爭(zhēng)片拍,改變命運(yùn)的戰(zhàn)略性知識(shí)。 社會(huì)上有2種人是不用營(yíng)銷的妓肢,一種是王思聰捌省,另外一種是喬布斯。王思聰...
    娜家亂燉閱讀 347評(píng)論 0 1