国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android動畫 實現(xiàn)開關(guān)按鈕動畫(屬性動畫之平移動畫)實例代碼

2019-12-12 04:47:37
字體:
供稿:網(wǎng)友

Android動畫 實現(xiàn)開關(guān)按鈕動畫(屬性動畫之平移動畫),最近做項目,根據(jù)項目需求,有一個這樣的功能,實現(xiàn)類似開關(guān)的動畫效果,經(jīng)過自己琢磨及上網(wǎng)查找資料,終于解決了,這里就記錄下:

  在Android里面,一些炫酷的動畫確實是很吸引人的地方,讓然看了就賞心悅目,一個好看的動畫可能會提高用戶對軟件的使用率。另外說到動畫,在Android里面支持3種動畫: 逐幀動畫(Frame Animation)、補間動畫(Tween Animation)和屬性動畫(Property Animation),至于這幾種動畫的區(qū)別這里不再介紹,希望開發(fā)者都能在使用的過程中體會兩者的不同。

  本文使用屬性動畫完成,說到屬性動畫,肯定要提到 JakeWharton大神寫的NineOldAndroids動畫庫,如果你的app需要在android3.0以下使用屬性動畫,那么這個庫就很有作用了,如果只需要在高版本使用,那么直接使用系統(tǒng)提供的動畫API即可。

首先看一下本文要實現(xiàn)的動畫效果:手指向上移動到開關(guān)按鈕處, 然后一個點擊動作,開關(guān)從關(guān)到開動畫執(zhí)行,同時手指向下移動回到原來的位置

點擊圖片調(diào)轉(zhuǎn)到對應(yīng)鏈接查看動畫

 動畫的使用場景

  引導(dǎo)用戶去打開某個功能的開關(guān)按鈕或者去打開系統(tǒng)的某項設(shè)置的時候,增加動畫可以提高用戶的點擊率,表達的意思也更明確

 實現(xiàn)之前先做好如下準備工作

  1. 下載nineoldandroids-2.4.0.jar的庫,放到android studio 工程目錄的libs文件夾中

  2. 在build.gradle文件中引入

dependencies { compile files('libs/nineoldandroids-2.4.0.jar')}

  3. 準備好相關(guān)的圖片資源

      

 接下來封裝一個自定義控件來實現(xiàn)整個動畫

第一步:先定義一個布局文件finger_switch_on_guide_layout.xml

<?xml version="1.0" encoding="utf-8"?><merge xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/switch_anim_root" android:layout_width="wrap_content" android:layout_height="wrap_content"> <FrameLayout  android:layout_width="wrap_content"  android:layout_height="wrap_content">  <ImageView   android:layout_width="42dp"   android:layout_height="25dp"   android:background="@drawable/switch_container" />  <ImageView   android:id="@+id/switch_anim_circle_point"   android:layout_width="20dp"   android:layout_height="20dp"   android:layout_marginLeft="2.5dp"   android:layout_marginTop="2.5dp"   android:background="@drawable/switch_off_circle_point" /> </FrameLayout> <ImageView  android:id="@+id/finger_switch"  android:layout_width="34dp"  android:layout_height="41dp"  android:layout_marginLeft="5dp"  android:layout_marginTop="25dp"  android:background="@drawable/finger_normal" /></merge>

布局文件預(yù)纜長這樣:

 第二步:定義自定義控件(SwitchOnAnimView)實現(xiàn)整個動畫

package com.androidanimation.animationview;import android.content.Context;import android.os.Handler;import android.util.AttributeSet;import android.view.LayoutInflater;import android.widget.FrameLayout;import android.widget.ImageView;import com.androidanimation.R;import com.androidanimation.animations.BaseAnimatorListener;import com.androidanimation.utils.ViewUtil;import com.nineoldandroids.animation.Animator;import com.nineoldandroids.animation.ObjectAnimator;import com.nineoldandroids.view.ViewHelper;/** * Created by popfisher on 2016/9/3. */public class SwitchOnAnimView extends FrameLayout { private Handler mHandler = new Handler(); /** 開關(guān)中間的圓圈View */ private ImageView mCirclePtImgv; /** 手指View */ private ImageView mFingerImgv; /** 手指移動的距離 */ private float mFingerMoveDistance; /** 開關(guān)中間的圓圈View需要移動的距離 */ private float mCirclePtMoveDistance; private static final int FINGER_ANIM_DURATION = 300; private static final int CIRCLE_PT_ANIM_DURATION = 500; private boolean isStopAnim = false; public SwitchOnAnimView(Context context) {  this(context, null); } public SwitchOnAnimView(Context context, AttributeSet attrs) {  super(context, attrs);  // 加載布局  LayoutInflater.from(context).inflate(R.layout.finger_switch_on_guide_layout, this, true);  initView(); } private void initView() {  mCirclePtImgv = (ImageView) findViewById(R.id.switch_anim_circle_point);  mFingerImgv = (ImageView) findViewById(R.id.finger_switch);  // 下面兩個距離要根據(jù)UI布局來確定  mFingerMoveDistance = ViewUtil.dp2px(getContext(), 20f);  mCirclePtMoveDistance = ViewUtil.dp2px(getContext(), 17.5f); } /**  * 啟動動畫  */ public void startAnim() {  isStopAnim = false;  // 啟動動畫之前先恢復(fù)初始狀態(tài)  ViewHelper.setTranslationX(mCirclePtImgv, 0);  mCirclePtImgv.setBackgroundResource(R.drawable.switch_off_circle_point);  mFingerImgv.setBackgroundResource(R.drawable.finger_normal);  startFingerUpAnim(); } /**  * 停止動畫  */ public void stopAnim() {  isStopAnim = true; } /**  * 中間的圈點View平移動畫  */ private void startCirclePointAnim() {  if (mCirclePtImgv == null) {   return;  }  ObjectAnimator circlePtAnim = ObjectAnimator.ofFloat(mCirclePtImgv, "translationX", 0, mCirclePtMoveDistance);  circlePtAnim.setDuration(CIRCLE_PT_ANIM_DURATION);  circlePtAnim.start(); } /**  * 手指向上移動動畫  */ private void startFingerUpAnim() {  ObjectAnimator fingerUpAnim = ObjectAnimator.ofFloat(mFingerImgv, "translationY", 0, -mFingerMoveDistance);  fingerUpAnim.setDuration(FINGER_ANIM_DURATION);  fingerUpAnim.addListener(new BaseAnimatorListener() {   @Override   public void onAnimationEnd(Animator animator) {    if (mFingerImgv == null || mHandler == null) {     return;    }    // 手指向上動畫執(zhí)行完成就設(shè)置手指View背景為點擊狀態(tài)的背景    mFingerImgv.setBackgroundResource(R.drawable.finger_click);    // 點擊之后為了提現(xiàn)停頓一下的感覺,延遲200毫秒執(zhí)行其他動畫    mHandler.postDelayed(new Runnable() {     @Override     public void run() {      if (mCirclePtImgv == null || mHandler == null) {       return;      }      // 將中間圓圈View背景設(shè)置為開關(guān)打開狀態(tài)然后開始向右平移      mCirclePtImgv.setBackgroundResource(R.drawable.switch_on_circle_point);      startCirclePointAnim();      // 延遲100毫秒啟動手指向下平移動畫      mHandler.postDelayed(new Runnable() {       @Override       public void run() {        // 手指向下移動開始時設(shè)置手指背景為正常的狀態(tài)        if (mFingerImgv != null) {         mFingerImgv.setBackgroundResource(R.drawable.finger_normal);        }        startFingerDownAnim();       }      }, 100);     }    }, 200);   }  });  fingerUpAnim.start(); } /**  * 手指向下移動動畫  */ private void startFingerDownAnim() {  if (mFingerImgv == null) {   return;  }  ObjectAnimator fingerDownAnim = ObjectAnimator.ofFloat(mFingerImgv, "translationY", -mFingerMoveDistance, 0);  fingerDownAnim.setDuration(FINGER_ANIM_DURATION);  fingerDownAnim.addListener(new BaseAnimatorListener() {   @Override   public void onAnimationEnd(Animator animator) {    // 手指向下移動動畫完成,整個動畫流程結(jié)束,重新開始下一次流程,循環(huán)執(zhí)行動畫,間隔1秒    mHandler.postDelayed(new Runnable() {     @Override     public void run() {      if (isStopAnim) {       return;      }      startAnim();     }    }, 1000);   }  });  fingerDownAnim.start(); }}

最后一步:就是找個載體把SwitchOnAnimView加進去,調(diào)用其startAnim方法執(zhí)行動畫,這里在一個Activity中把播放此動畫

定義activity布局文件activity_finger_switchon_anim.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_animation_main" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <com.androidanimation.animationview.SwitchOnAnimView  android:id="@+id/switch_on_anim_view"  android:layout_width="wrap_content"  android:layout_height="wrap_content"/></LinearLayout>

定義并實現(xiàn)Activity:FingerSwitchOnAnimActivity

package com.androidanimation;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import com.androidanimation.animationview.SwitchOnAnimView;public class FingerSwitchOnAnimActivity extends Activity { private Handler mHandler = new Handler(); private SwitchOnAnimView mSwitchOnAnimView; @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_finger_switchon_anim);  mSwitchOnAnimView = (SwitchOnAnimView) findViewById(R.id.switch_on_anim_view);          mHandler.postDelayed(new Runnable() {   @Override   public void run() {    mSwitchOnAnimView.startAnim();   }  }, 500);} }

動畫實現(xiàn)總結(jié):

  掌握Android的動畫并不難,難的時候怎么實現(xiàn)一些復(fù)雜的動畫,這里總結(jié)一下實現(xiàn)復(fù)雜動畫的幾個步驟。

  1. 動畫分解:任何復(fù)雜的動畫都可以分解為很多個原子動畫的組合

  2. 動畫銜接時機分析:復(fù)雜動畫分解為很多個原子動畫之后,要重新銜接起來

            這里其實就是各個原子動畫的執(zhí)行時機,誰先誰后還是同時執(zhí)行

  3. 實現(xiàn)原子動畫:將拆解的原子動畫依次實現(xiàn)

  4. 動畫組裝:上面都準備好之后,將原子動畫按照一定的規(guī)律組裝串聯(lián)起來,整個復(fù)雜的動畫就開始工作了

  原子動畫:本文指不能再繼續(xù)拆分的動畫

  拿本文中的動畫來說,動畫可以分為四個:

  a. 手指向上平移動畫

  b. 手指點擊操作(這里不是動畫,也可以當做一個簡單的動畫吧)

  c. 開關(guān)按鈕原點向右平移動畫

  d. 手指向下平移動畫。

  本文動畫執(zhí)行時機為:

  a 先執(zhí)行,a 執(zhí)行完成之后立即執(zhí)行 b,b 執(zhí)行完成之后等待200ms執(zhí)行 c(體現(xiàn)點擊效果)

  c 執(zhí)行開始100ms后開始執(zhí)行 d

  動畫的分解和動畫銜接時機分析是不太容易的事,因為憑借肉眼有時候沒法觀察出來,所以播放動畫的時候要放慢來看,如果還是不能看出來,最好還是要找公司的UI同事協(xié)助分析。因為我們能簡單的區(qū)分平移動畫,縮放動畫這種簡單,但是我們不能區(qū)分那種正弦算法動畫或者是另外一些其他算法控制的動畫。本文中的動畫相對還是比較簡單,實現(xiàn)起來也比較容易,但是思想確實一樣的。

 源碼下載地址:https://github.com/PopFisher/AndroidAnimationDemos

        感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 浙江省| 灵宝市| 察隅县| 安徽省| 永康市| 武邑县| 澄迈县| 乳山市| 通河县| 吴旗县| 城市| 广丰县| 钦州市| 筠连县| 杨浦区| 平泉县| 萨嘎县| 海晏县| 晴隆县| 石嘴山市| 融水| 雅江县| 鄂托克旗| 玛多县| 临猗县| 长葛市| 浮梁县| 阳山县| 平潭县| 兴义市| 阳朔县| 安仁县| 独山县| 德保县| 铁力市| 和顺县| 威远县| 尼勒克县| 阳春市| 扶风县| 杭锦旗|