編輯:關於android開發
動畫效果可以大大提高界面的交互效果,因此,動畫在移動開發中的應用場景較為普遍。掌握基本的動畫效果在成熟的軟件開發中不可或缺。除此之外,用戶對於動畫的接受程度遠高於文字和圖片,利用動畫效果可以加深用戶對於產品的印象。因此本文給出安卓設計中幾種常見的動畫效果。
基礎知識
在介紹安卓中的動畫效果之前,有必要介紹一下安卓中的圖片處理機制。圖片的特效包括圖形的縮放、鏡面、倒影、旋轉、平移等。圖片的特效處理方式是將原圖的圖形矩陣乘以一個特效矩陣,形成一個新的圖形矩陣來實現的。矩陣Matrix 類,維護了一個3*3 的矩陣去更改像素點的坐標。Android 手機的屏幕坐標系以左上角為原點,從左向右為x軸正方向,從上到下為y軸正方向。第一行表示像素點的x 坐標:x = 1*x + 0*y + 0*z,第二行表示像素點的y 坐標:y = 0*x + 1*y + 0*z,第三行表示像素點的z 坐標:z = 0*x + 0*y + 1*z。圖片的特效處理正是通過更改圖形矩陣的值來實現的,在android下Matrix這個類幫我們封裝了矩陣的一些基本用法,所以我們可以直接使用即可。用代碼編輯圖片,最好處理都是圖片在內存中的拷貝,不去處理原圖,因此需要用Bitmap創建一個與原圖大小一致,格式相同的空白位圖。
對照片進行操作的基本步驟:
1. 創建一個空白的bitmap,寬高信息和原圖保存一致;
2. 創建一個畫板;
3. 創建一個畫筆;
4. 設置matrix矩陣;
5. 對照著原圖在畫紙上面畫出一模一樣的樣子出來。
下面分別給出對圖片縮放、平移、旋轉、鏡面操作的代碼。
/**
* 圖片縮放
*
*/
private void zoom() {
Bitmap srcBitmap = BitmapFactory.decodeFile("mnt/sdcard/b.jpg");
iv_src.setImageBitmap(srcBitmap);
Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
Canvas canvas = new Canvas(copyBitmap);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
Matrix matrix = new Matrix();
matrix.setScale(0.6f, 0.6f);
canvas.drawBitmap(srcBitmap, matrix, paint);
iv_dest.setImageBitmap(copyBitmap);
}
/**
* 圖片平移
*
*/
public void translation(){
Options ops = new Options();
ops.inSampleSize = 4; //等比放縮
Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/b.jpg",ops);
iv_src.setImageBitmap(srcBitmap);
Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
Canvas canvas = new Canvas(copyBitmap);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
Matrix matrix = new Matrix();
matrix.setTranslate(100, 100);
canvas.drawBitmap(srcBitmap, matrix, paint);
iv_dest.setImageBitmap(copyBitmap);
}
/**
* 旋轉
*
*/
public void scole(){
Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/b.jpg");
iv_src.setImageBitmap(srcBitmap);
Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
Canvas canvas = new Canvas(copyBitmap);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
Matrix matrix = new Matrix();
matrix.setRotate(180, srcBitmap.getWidth()/2, srcBitmap.getHeight()/2);//繞原點旋轉
canvas.drawBitmap(srcBitmap, matrix, paint);
iv_dest.setImageBitmap(copyBitmap);
}
/**
* 鏡面特效/倒影特效
* 原理一樣,一個關於x軸旋轉,一個關於y軸旋轉
*/
public void mirror(){
Bitmap srcBitmap = BitmapFactory.decodeFile("/mnt/sdcard/b.jpg");
iv_src.setImageBitmap(srcBitmap);
Bitmap copyBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), srcBitmap.getConfig());
Canvas canvas = new Canvas(copyBitmap);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
Matrix matrix = new Matrix();
matrix.setScale(-1, 1);
matrix.postTranslate(srcBitmap.getWidth(), 0);
canvas.drawBitmap(srcBitmap, matrix, paint);
iv_dest.setImageBitmap(copyBitmap);
}
接下來進入進入今天的主題。安卓下的動畫分為三種: 幀動畫、View動畫(補間動畫)、屬性動畫。下面分別介紹這三種動畫。
幀動畫:
幀動畫是這三種動畫中最為普遍的一種,指的是一幀一幀播放的動畫。更直白的講就是快速切換圖片的效果。通過animation-list來實現,創建一個Drawable 序列,這些Drawable 可以按照指定的時間間隔一個一個的顯示,也就是順序播放事先做好的圖像。
幀動畫使用的基本步驟:
1 . 創建幀動畫每幀需要的圖片, 放到對應的 drawable-xxx 或drawable 目錄中
2 . 在drawable 目錄下,創建幀動畫 xml 文件,根節點選擇 animation-list。oneshot屬性表示幀動畫的自動執行。 如果為true,表示動畫只播放一次停止在最後一幀上,如果設置為false表示動畫循環播放。
3. 在JAVA代碼中開啟動畫。設置為 View 的 Background 或者 ImageView 的 src,然後獲取到控件的 AnimationDrawable 對象,通過 AnimationDrawable.start() 方法啟動動畫
下面以火箭的發射為例演示幀動畫。
xml文件中的代碼:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/desktop_rocket_launch_1" android:duration="200" /> <item android:drawable="@drawable/desktop_rocket_launch_2" android:duration="200" /> </animation-list>
Java代碼的實現:
iv = new ImageView(this);
//開啟幀動畫 rocket為上述xml文件
iv.setBackgroundResource(R.drawable.rocket);
AnimationDrawable ad = (AnimationDrawable) iv.getBackground();
ad.start();
屬性動畫:
Android 3.0之後view類增加新的用來記錄動畫行為的屬性,只能運行的Android3.0以上的系統也就是說 運行在 API-11 以上的系統。屬性動畫會改變當前的視圖所在的位置,通過動態改變控件的寬、高、坐標等屬性而產生的動畫效果。
通過控制控件的屬性實現動畫效果,屬性動畫比補間動畫要更靈活、強大的多。需要注意的是屬性動畫內部其實並沒有區分位移、縮放、透明、旋轉等動畫,其核心思想只是修改一個控件的屬性,我們可以通過修改不同的屬性來實現補間動畫的4 種效果而已。
屬性動畫跟補間動畫比,屬性動畫是真正改變了控件的屬性,會改變當前的視圖所在的位置,因此當控件的位置改變後只要點擊到了控件“身上”就能觸發onClick 事件。而補間動畫則並沒用改變控件的真實屬性,因此不管屬性動畫執行後將控件移動到了哪個位置,只能通過點擊該控件的原始位置才能觸發onClick 事件。
通過xml 文件實現屬性動畫步驟:
1. 在res 下創建屬性動畫文件。在res 目錄下創建animator 文件夾,然後創建一個objectAnimator 資源文件。資源名稱自定義即可。
2. 編寫屬性動畫文件。指定屬性值。
3. 編寫代碼使用屬性動畫文件。通過AnimatorInflater加載圖片資源,指定要顯示動畫的控件,並開啟動畫。
屬性動畫可以通過xml文件實現,但通常屬性動畫是通過JAVA代碼實現。這裡僅給出用xml文件實現淡化動畫的案例,其他案例均以JAVA代碼的方式實現。
JAVA代碼的方式實現屬性動畫。
public class MainActivity extends Activity {
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.iv);
}
/**
* 淡化動畫
* @param view
*/
public void alpha(View view) {
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "alpha", new float[] {
0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f });
oa.setDuration(3000);
oa.setRepeatCount(ObjectAnimator.INFINITE);
oa.setRepeatMode(ObjectAnimator.REVERSE);
oa.start();
}
/**
* 平移動畫
* @param view
*/
public void trans(View view) {
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX",
new float[] { 10f, 20f, 30f, 40f, 60f, 80f });
oa.setDuration(3000);
oa.setRepeatCount(ObjectAnimator.INFINITE);
oa.setRepeatMode(ObjectAnimator.REVERSE);
oa.start();
}
/**
* 縮放動畫
*/
public void scale(View view) {
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "scaleX", new float[] {
1f, 2f, 3f, 4f, 5f, 6f });
oa.setDuration(3000);
oa.setRepeatCount(ObjectAnimator.INFINITE);
oa.setRepeatMode(ObjectAnimator.REVERSE);
oa.start();
}
/**
* 旋轉動畫
*/
public void rotate(View view) {
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "rotationY",
new float[] { 90f, 180f, 270f, 360f });
oa.setDuration(3000);
oa.setRepeatCount(ObjectAnimator.INFINITE);
oa.setRepeatMode(ObjectAnimator.REVERSE);
oa.start();
}
/**
* 水平平移 + 豎直平移
*/
public void set(View view) {
AnimatorSet set = new AnimatorSet();
ObjectAnimator oa = ObjectAnimator.ofFloat(iv, "translationX",
new float[] { 10f, 20f, 30f, 40f, 60f, 80f });
oa.setDuration(3000);
ObjectAnimator oa2 = ObjectAnimator.ofFloat(iv, "translationY",
new float[] { -10f, -20f, -30f, -40f, -60f, -80f });
oa2.setDuration(3000);
set.playTogether(oa, oa2);
set.start();
}
}
xml文件實現淡化效果:
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:propertyName="alpha"
android:repeatCount="3"
android:repeatMode="reverse"
android:valueFrom="0.0"
android:valueTo="1.0" >
</objectAnimator>
然後在java代碼中實現這樣一段代碼:
public void alpha(View view) {
Animator animator = AnimatorInflater.loadAnimator(this,
R.animator.alpha);
animator.setTarget(iv);
animator.start();
}
View動畫:
漸變動畫也叫補間動畫。補間動畫通過對View 的內容進行一系列的圖形變換(包括平移、縮放、旋轉、改變透明度)來實現動畫效果。動畫效果的定義可以采用XML 文件來做也可以采用java 代碼來做。
使用XML 文件實現View動畫的步驟:
1. 在res 目錄下創建anim 文件夾。
2. 在anim 文件夾中創建xml文件,文件名可以自定義。
3. 編輯xml文件。定義不同的標簽,表示不同的動畫效果。alpha表示淡化,
4. 添加Java 邏輯代碼,使用AnimationUtils 工具類加載xml 文件,獲取Animation 對象,調用startAnimation 讓ImageView 執行此動畫。
View動畫中常用屬性的含義:
duration 動畫時長
fromAlpha 起始透明度,1 為完全不透明,0 為完全透明
repeatCount 重復次數,INFINITE表示無限重復
toAlpha 目標透明度
repeatMode 重復模式,restart 為重新開始,reverse表示來回播放
漸變動畫在代碼中使用的是AlphaAnimation 類來定義,在XML 文件中使用<alpha>節點來定義。旋轉動畫在代碼中使用的是RotateAnimation 類來定義,在XML 文件中使用<rotate>節點來定義。伸縮動畫在代碼中使用的是ScaleAnimation 類來定義,在XML 文件中使用<scale>節點來定義。平移動畫在代碼中使用的是TranslateAnimation 類來定義,在XML 文件中使用<scale>節點來定義。Android 提供了AnimationSet 動畫集合用於將多種補間動畫聯合起來一起使用,這樣就能實現更多復雜的動畫效果。動畫集合既可以使用AnimationSet 類來定義也可以在XML 文件中使用<set>節點來定義。任何復雜的動畫均是通過簡單的動畫集合在一起的。
使用編碼方式同樣可以實現view動畫,直接創建相應的動畫對象,然後添加相應的屬。代使用編碼方式實現view動畫跟用XML 文件實現View動畫其實是一模一樣的,無非就是在JAVA代碼中設定相關的屬性罷了。
使用XML 文件實現View動畫的代碼:
1 . 在anim文件夾下新建下列文件:
<!-- alpha_demo.xml 文件夾下 -->
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromAlpha="0.0"
android:repeatCount="infinite"
android:repeatMode="reverse"
android:toAlpha="1.0" >
</alpha>
<!-- rotate_demo.xml 文件夾下 -->
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="2"
android:repeatMode="reverse"
android:toDegrees="360" >
</rotate>
<!-- scale_demo.xml 文件夾下 -->
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXScale="20%"
android:fromYScale="20%"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="2"
android:repeatMode="reverse"
android:toXScale="200%"
android:toYScale="200%" >
</scale>
<!-- set_demo.xml 文件夾下 -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true" >
<rotate
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="2"
android:repeatMode="reverse"
android:toDegrees="360" >
</rotate>
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXScale="20%"
android:fromYScale="20%"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="2"
android:repeatMode="reverse"
android:toXScale="200%"
android:toYScale="200%" >
</scale>
</set>
<!-- trans_demo.xml 文件夾下 -->
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXDelta="0"
android:fromYDelta="0"
android:repeatCount="2"
android:repeatMode="reverse"
android:toXDelta="100%"
android:toYDelta="100%" >
</translate>
2 . 在java代碼中實現下列邏輯:
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.iv);
}
/**
* 淡化動畫
* @param view
*/
public void alpha(View view){
Animation aa = AnimationUtils.loadAnimation(this, R.anim.alpha_demo);
iv.startAnimation(aa);
}
/**
* 平移動畫
* @param view
*/
public void trans(View view){
Animation ta = AnimationUtils.loadAnimation(this, R.anim.trans_demo);
iv.startAnimation(ta);
}
/**
* 縮放動畫
*/
public void scale(View view){
Animation sa = AnimationUtils.loadAnimation(this, R.anim.scale_demo);
iv.startAnimation(sa);
}
/**
* 旋轉動畫
*/
public void rotate(View view){
Animation ra = AnimationUtils.loadAnimation(this, R.anim.rotate_demo);
iv.startAnimation(ra);
}
/**
* 旋轉 + 放縮
*/
public void set(View view){
Animation set = AnimationUtils.loadAnimation(this, R.anim.set_demo);
iv.startAnimation(set);
}
}
使用java代碼實現View動畫的代碼
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.RotateAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;
public class MainActivity extends Activity {
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = (ImageView) findViewById(R.id.iv);
}
/**
* 漸變動畫
* @param view
*/
public void alpha(View view) {
AlphaAnimation aa = new AlphaAnimation(0.0f, 1.0f);
aa.setDuration(2000);
aa.setRepeatCount(Animation.INFINITE);
aa.setRepeatMode(Animation.REVERSE);
iv.startAnimation(aa);
}
/**
* 平移動畫
* @param view
*/
public void trans(View view) {
TranslateAnimation ta = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1f,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1f);
ta.setDuration(2000);
ta.setRepeatCount(Animation.INFINITE);
ta.setRepeatMode(Animation.REVERSE);
iv.startAnimation(ta);
}
/**
* 縮放動畫
*/
public void scale(View view) {
ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
sa.setDuration(2000);
sa.setRepeatCount(Animation.INFINITE);
sa.setRepeatMode(Animation.REVERSE);
iv.startAnimation(sa);
}
/**
* 旋轉動畫
*/
public void rotate(View view) {
RotateAnimation ra = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
ra.setDuration(2000);
ra.setRepeatCount(Animation.INFINITE);
ra.setRepeatMode(Animation.REVERSE);
iv.startAnimation(ra);
}
/**
* 旋轉 + 平移 + 放縮
* AnimationSet添加各個動畫
*/
public void set(View view) {
AnimationSet set = new AnimationSet(false);
RotateAnimation ra = new RotateAnimation(0, 360,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
ra.setDuration(2000);
ra.setRepeatCount(Animation.INFINITE);
ra.setRepeatMode(Animation.REVERSE);
ScaleAnimation sa = new ScaleAnimation(0.2f, 2.0f, 0.2f, 2.0f,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
sa.setDuration(2000);
sa.setRepeatCount(Animation.INFINITE);
sa.setRepeatMode(Animation.REVERSE);
TranslateAnimation ta = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1f,
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 1f);
ta.setDuration(2000);
ta.setRepeatCount(Animation.INFINITE);
ta.setRepeatMode(Animation.REVERSE);
set.addAnimation(ta);
set.addAnimation(sa);
set.addAnimation(ra);
iv.startAnimation(set);
}
}
自此Android下的三種動畫全部講解完畢。
android中菜單(menu)的基本知識,androidmenu
android中菜單(menu)的基本知識,androidmenu(一)選項菜單 1、簡單的創建菜單: 1 @Override 2 public boole
android:QQ多種側滑菜單的實現
android:QQ多種側滑菜單的實現 然而這個菜單效果只是普通的側拉效果 我們還可以實現抽屜式側滑菜單 就像這樣 第一種效果 第二種效果 第三種效果 第四種效果 其
Android 自定義控件之第三講:obtainStyledAttributes 系列函數詳解
Android 自定義控件之第三講:obtainStyledAttributes 系列函數詳解 在項目中開發自定義控件時,或多或少都會用到 obtainStyledAtt
VS2015牆內創建ionic2,vs2015牆ionic2
VS2015牆內創建ionic2,vs2015牆ionic2 開始學習ionic2,試驗各種方法,感覺以下是緊跟rc版本的