Android自定義View動畫
阿新 • • 發佈:2018-12-14
執行效果:
前言:
Android系統提供了兩個動畫框架:屬性動畫框架和View動畫框架。 兩個動畫框架都是可行的選項,但是屬性動畫框架通常是首選的使用方法,因為它更靈活,並提供更多的功能。 除了這兩個框架,還可以使用Drawable動畫(即逐幀動畫,AnimationDrawable),它允許你載入Drawable資源並逐幀地顯示它們。
View動畫框架中一共提供了AlphaAnimation(透明度動畫)、RotateAnimation(旋轉動畫)、ScaleAnimation(縮放動畫)、TranslateAnimation(平移動畫)四種類型的補間動畫;並且View動畫框架還提供了動畫集合類(AnimationSet),通過動畫集合類(AnimationSet)可以將多個補間動畫以組合的形式顯示出來;當然如果對提供的型別動畫不滿意,可以自定義動畫!
View佈局:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <Button android:id="@+id/btnAlpha" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginTop="80dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:background="@color/colorAccent" android:text="@string/animation_me" android:textAllCaps="false" android:textColor="@android:color/background_light" android:textSize="30sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/btnRotate" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:background="@color/colorPrimary" android:text="@string/rotate_animation" android:textAllCaps="false" android:textColor="@android:color/background_light" android:textSize="24sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/btnAlpha" /> <Button android:id="@+id/btnTranslate" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:background="@color/colorPrimaryDark" android:text="@string/translate_animation" android:textAllCaps="false" android:textColor="@android:color/background_light" android:textSize="24sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/btnRotate" /> <Button android:id="@+id/btnScale" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:background="@android:color/holo_orange_dark" android:text="@string/scale_animation" android:textAllCaps="false" android:textColor="@android:color/background_light" android:textSize="24sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/btnTranslate" /> <Button android:id="@+id/btnBlend" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:background="@android:color/background_dark" android:text="@string/blend_animation" android:textAllCaps="false" android:textColor="@android:color/background_light" android:textSize="30sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/btnScale" /> <Button android:id="@+id/btnListener" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:background="@android:color/holo_green_dark" android:text="@string/listener_animation" android:textAllCaps="false" android:textColor="@android:color/background_light" android:textSize="24sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/btnBlend" /> <Button android:id="@+id/btnCustom" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:background="@android:color/holo_red_light" android:text="@string/custom_animation" android:textAllCaps="false" android:textColor="@android:color/background_light" android:textSize="24sp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/btnListener" /> </android.support.constraint.ConstraintLayout>
Control層:
MainActivity.java:
public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button btnAlpha,btnRotate,btnTranslate,btnScale,btnBlend,btnListener,btnCustom; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } public void initView(){ btnAlpha=findViewById(R.id.btnAlpha); btnRotate=findViewById(R.id.btnRotate); btnTranslate=findViewById(R.id.btnTranslate); btnScale=findViewById(R.id.btnScale); btnBlend=findViewById(R.id.btnBlend); btnListener=findViewById(R.id.btnListener); btnCustom=findViewById(R.id.btnCustom); btnAlpha.setOnClickListener(this); btnRotate.setOnClickListener(this); btnTranslate.setOnClickListener(this); btnScale.setOnClickListener(this); btnBlend.setOnClickListener(this); btnListener.setOnClickListener(this); btnCustom.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.btnAlpha: //方法一:Java程式配置動畫 // AlphaAnimation animation=new AlphaAnimation(0,1);//透明度從零到一 // animation.setDuration(2000);//動畫時長 // v.startAnimation(animation);//按鈕開啟動畫 //方法二:使用佈局檔案來配置動畫 v.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.alpha)); break; case R.id.btnRotate: //方法一:Java程式配置動畫 // RotateAnimation rotateAnimation=new RotateAnimation(0,360, // Animation.RELATIVE_TO_SELF,0.5f, // Animation.RELATIVE_TO_SELF,0.5f);//零到360度,旋轉點為控制元件相對中心 // rotateAnimation.setDuration(2000); // v.startAnimation(rotateAnimation); //方法二:使用佈局檔案來配置動畫 v.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.rotate)); break; case R.id.btnTranslate: // TranslateAnimation translateAnimation=new TranslateAnimation(0,200, // 0,200);//從原位置向x、y方向各移動200畫素 // translateAnimation.setDuration(2000); // v.startAnimation(translateAnimation); v.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.translate)); break; case R.id.btnScale: // ScaleAnimation scaleAnimation=new ScaleAnimation(0,1,0,1, // Animation.RELATIVE_TO_SELF,0.5f, // Animation.RELATIVE_TO_SELF,0.5f);//縮放從零到一,縮放點相對於自身中心 // scaleAnimation.setDuration(2000); // v.startAnimation(scaleAnimation); v.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.scale)); break; case R.id.btnBlend: //動畫集合類AnimationSet // AnimationSet animationSet=new AnimationSet(true);//各動畫共用動畫補間 // 補間動畫是一種設定動畫開始狀態、結束狀態,其中間的變化由系統計算補充。 // animationSet.setDuration(2000); // // RotateAnimation rotateAnimation=new RotateAnimation(0,360, // Animation.RELATIVE_TO_SELF,0.5f, // Animation.RELATIVE_TO_SELF,0.5f); // rotateAnimation.setDuration(1000); // animationSet.addAnimation(rotateAnimation);//集合中新增子動畫 // ScaleAnimation scaleAnimation=new ScaleAnimation(0,1,0,1, // Animation.RELATIVE_TO_SELF,0.5f, // Animation.RELATIVE_TO_SELF,0.5f); // scaleAnimation.setDuration(1000); // animationSet.addAnimation(scaleAnimation); // v.startAnimation(animationSet); v.startAnimation(AnimationUtils.loadAnimation(MainActivity.this,R.anim.blend)); break; case R.id.btnListener: Animation animation=AnimationUtils.loadAnimation(MainActivity.this,R.anim.blend); animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { Toast.makeText(MainActivity.this,"動畫開始!",Toast.LENGTH_SHORT).show(); } @Override public void onAnimationEnd(Animation animation) { Toast.makeText(MainActivity.this,"動畫結束!",Toast.LENGTH_SHORT).show(); } @Override public void onAnimationRepeat(Animation animation) { //動畫重複執行 } }); v.startAnimation(animation); break; case R.id.btnCustom: CustomAnimation customAnimation=new CustomAnimation(); v.startAnimation(customAnimation); } } }
CustomAnimation.java:
public class CustomAnimation extends Animation {
//動畫初始化,用來設定動畫的基本屬性
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
setDuration(2000);//設定動畫時長
}
//該方法用來實現動畫,
// interpolatedTime表示插值器的時間因子,補間時間,取值範圍0-1
// t一個矩陣的封裝類,實現動畫就是利用矩陣來計算的
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
//t.setAlpha(interpolatedTime);//透明效果
//Matrix可將一個點對映到另一個點,矩陣中包含了處理縮放、透視以及平移的區域,從而可用於控制實現平移、縮放、旋轉等動畫效果。
//t.getMatrix().setTranslate(interpolatedTime*200,interpolatedTime*200);//平移效果
t.getMatrix().setTranslate((float) (Math.sin(interpolatedTime*20)*50),0);//使用周期函式實現搖頭效果
}
}
資源配置檔案:
alpha.xml
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="0"
android:toAlpha="1"
android:duration="2000">
</alpha>
rotate.xml
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:duration="2000"
android:pivotX="50%"
android:pivotY="50%">
</rotate>
scale.xml
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXScale="0"
android:toXScale="1"
android:fromYScale="0"
android:toYScale="1"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000">
</scale>
translate.xml
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:toXDelta="200"
android:fromYDelta="0"
android:toYDelta="200"
android:duration="2000">
</translate>
blend.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true"
android:duration="2000">
<rotate android:fromDegrees="0"
android:toDegrees="360"
android:duration="1000"
android:pivotX="50%"
android:pivotY="50%">
</rotate>
<scale android:fromXScale="0"
android:toXScale="1"
android:fromYScale="0"
android:toYScale="1"
android:duration="1000"
android:pivotX="50%"
android:pivotY="50%">
</scale>
</set>
技術部落格: