鍍金池/ 教程/ Android/ layoutAnimation 與 gridLayoutAnimation
聯(lián)合動畫的 XML 實現(xiàn)與使用示例
Interpolator 插值器
高級進階(二)
ObjectAnimator 基本使用
ValueAnimator 基本使用
alpha、scale、translate、rotate、set 的 xml 屬性及用法
PropertyValuesHolder 與 Keyframe
layoutAnimation 與 gridLayoutAnimation
自定義控件三部曲之動畫篇(十三)——實現(xiàn)ListView Item進入動畫
自定義控件三部曲之動畫篇(十二)——animateLayoutChanges與LayoutTransition
高級進階(一)
代碼生成 alpha、scale、translate、rotate、set 及插值器動畫
聯(lián)合動畫的代碼實現(xiàn)

layoutAnimation 與 gridLayoutAnimation

前幾篇給大家講述了如何針對某一個控件應用動畫,這篇將給大家講解如何給容器中的控件應用統(tǒng)一動畫。即在容器中控件出現(xiàn)時,不必為每個控件添加進入動畫,可以在容器中為其添加統(tǒng)一的進入和退出動畫。

http://wiki.jikexueyuan.com/project/android-animation/images/112.gif" alt="" />

從上面的示例動畫也可以看出,listview 中的數(shù)據(jù)在進入時就加入了統(tǒng)一動畫,下面我們就來看看這些是怎么來實現(xiàn)的吧。 這篇我們將講述有關(guān)普通 viewGroup 添加進入統(tǒng)一動畫的 LayoutAnimation 和針對 grideView 添加進入動畫的 gridLayoutAnimation; LayoutAnimation 和 gridLayoutAnimation 在 API 1 中就有的函數(shù)。所有大家不必擔心他們的所能使用的 api 等級;也正因為他們是在 API 1 中就引入了,所以他們也只能使用 animtion 來做動畫,而不能使用 animator。

一、LayoutAnimation 的 xml 實現(xiàn)——layoutAnimation 標簽

1、概述

這部分,我們就來看看 layoutAnimation 標簽的用法,要使用 layoutAnimation 只需要兩步: 第一:定義一個 layoutAnimation 的 animation 文件,如:(anim/layout_animation.xml)

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                 android:delay="1"
                 android:animationOrder="normal"
                 android:animation="@anim/slide_in_left"/>

有關(guān)它的具體意義,我們后面會講。 第二步:在 viewGroup 類型的控件中,添加 android:layoutAnimation=”@anim/layout_animation”,如:

<ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layoutAnimation="@anim/layout_animation"
        />

2、示例

這部分,我們將要實現(xiàn)的效果圖如下:

http://wiki.jikexueyuan.com/project/android-animation/images/113.gif" alt="" />

從效果圖中,可以看出兩點:

  • listview 中各個 item 從左至右滑入位置
  • 動畫僅在第一次創(chuàng)建時有用,后期加入的數(shù)據(jù),將不會再有動畫(這個問題最后再講)

這里添加的 layoutAnimation,與上面的 layout_animation.xml 文件一樣:

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                 android:delay="1"
                 android:animationOrder="normal"
                 android:animation="@anim/slide_in_left"/>

其中的@anim/slide_in_left 對應代碼為:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000">
    <translate android:fromXDelta="-50%p" android:toXDelta="0"/>
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"/>
</set>

這部分實現(xiàn)的效果是,讓控件從左邊 50%的位置進入屏幕,同時透明度從 0 變到 1;動畫總時長為 1000 毫秒。 然后看 main.xml 的布局代碼,根據(jù)效果圖中也很容易看出布局代碼:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="刷新 list"/>

    <ListView
            android:id="@+id/listview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layoutAnimation="@anim/layout_animation"/>
</LinearLayout>

這里最重要的是,在 listView 中添加上 android:layoutAnimation=”@anim/layout_animation”來指定創(chuàng)建布局時,其中的子 item 所使用的動畫。 最后是 MyActivity 中填充 listview 的代碼:

public class MyActivity extends Activity {

    private ListView mListView;
    private ArrayAdapter mAdapter;
    private Button mAddListBtn;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mListView = (ListView) findViewById(R.id.listview);
        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, getData());
        mListView.setAdapter(mAdapter);

        mAddListBtn = (Button)findViewById(R.id.addlist);
        mAddListBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mAdapter.addAll(getData());
            }
        });
    }

    private List<String> getData() {
        List<String> data = new ArrayList<String>();
        data.add("測試數(shù)據(jù) 1");
        data.add("測試數(shù)據(jù) 2");
        data.add("測試數(shù)據(jù) 3");
        data.add("測試數(shù)據(jù) 4");

        return data;
    }
}

這段代碼理解起來難度不大,主要就是兩個點,第一:填充 listview,第二在點擊添加 list 數(shù)據(jù)按鈕時,向 Listview 添加新的數(shù)據(jù)。 最終的效果圖在本部分開頭就已經(jīng)給出。通過這個例子,我們可以知道最重要的一點:android:layoutAnimation 只在 viewGroup 創(chuàng)建的時候,才會對其中的 item 添加動畫。在創(chuàng)建成功以后,再向其中添加 item 將不會再有動畫。 我們可以看出,只需要在 viewGroup 控件中添加 android:layoutAnimation="@anim/layout_animation",就可以實現(xiàn)其容器內(nèi)部控件創(chuàng)建時的動畫。

3、layoutAnimation 各字段意義

上面我們講了 layoutAnimation 的使用方法,下面我們就來看看 layoutAnimation 標簽中各個字段的意義。 在 layoutAnimation 中,只有三個字段是有效的,分別是:android:delay、android:animationOrder 和 android:animation;其它諸如 android:duration、android:interpolator 等針對 animation 的字段都是無效的。下面我們結(jié)合上面的 layoutAnimation 代碼,來看一下各個字段的具體意義:

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                 android:delay="1"
                 android:animationOrder="normal"
                 android:animation="@anim/slide_in_left"/>
  • delay:指每個 Item 的動畫開始延時,取值是 android:animation 所指定動畫時長的倍數(shù),取值類型可以是 float 類型,也可以是百分數(shù),默認是 0.5;比如我們這里指定的動畫是@anim/slide_in_left,而在 slide_in_left.xml 中指定 android:duration=”1000”,即單次動畫的時長是 1000 毫秒,而我們在這里的指定 android:delay=”1”,即一個 Item 的動畫會在上一個 item 動畫完成后延時單次動畫時長的一倍時間開始,即延時 1000 毫秒后開始。
  • animationOrder:指 viewGroup 中的控件動畫開始順序,取值有 normal(正序)、reverse(倒序)、random(隨機)
  • animation:指定每個 item 入場所要應用的動畫。僅能指定 res/aim 文件夾下的 animation 定義的動畫,不可使用 animator 動畫。

這里最難理解的參數(shù)應該是 android:delay,它是指 viewGroup 中各個 item 開始動畫的時間延遲,取值是 Item 動畫時長的倍數(shù)。其中 item 動畫是通過 android:animation 指定的。 其次就是 animationOrder 的三種次序,其實也沒什么難度,我們就直接通過動畫來看看它們的區(qū)別吧。上面的效果圖中,我們演示的 normal(正序),下面我們再來看看 reverse 和 random 的效果圖: android:animationOrder=”reverse”(倒序)

http://wiki.jikexueyuan.com/project/android-animation/images/114.gif" alt="" />

android:animationOrder=”random”(隨機)

http://wiki.jikexueyuan.com/project/android-animation/images/115.gif" alt="" />

源碼在文章底部給出

二、LayoutAnimation 的代碼實現(xiàn)——LayoutAnimationController

1、概述

上面我們講過了 LayoutAnimation 的 xml 實現(xiàn)方式,下面來看看 LayoutAnimation 的代碼實現(xiàn)方式。 首先,xml 中 layoutAnimation 標簽所對應的類為 LayoutAnimationController;它有兩個構(gòu)造函數(shù):

public LayoutAnimationController(Animation animation)
public LayoutAnimationController(Animation animation, float delay)

很容易理解,animation 對應標簽中的 android:animation 屬性,delay 對應標簽中的 android:delay 屬性。 LayoutAnimationController 的函數(shù)如下:

/**
 * 設(shè)置 animation 動畫
 */
public void setAnimation(Animation animation)
/**
 * 設(shè)置單個 item 開始動畫延時
 */
public void setDelay(float delay)
/**
 * 設(shè)置 viewGroup 中控件開始動畫順序,取值為 ORDER_NORMAL、ORDER_REVERSE、ORDER_RANDOM
 */
public void setOrder(int order)

這些函數(shù)都很容易理解,與 xml 中標簽的意義完全相同。下面我們就來看看使用方法。

2、示例

同樣以上面的例子為例,把 xml 實現(xiàn)改成代碼實現(xiàn)。由于我們要代碼實現(xiàn) layoutAnimation,所以我們不再需要寫 layoutAnimation 的 xml 了,只需要一個動畫的 animation:(slide_in_left.xml)

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000">
    <translate android:fromXDelta="-50%p" android:toXDelta="0"/>
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"/>
</set>

然后是主布局(main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <Button
            android:id="@+id/addlist"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="添加 list 數(shù)據(jù)"/>

    <ListView
            android:id="@+id/listview"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
</LinearLayout>

布局與 xml 的實現(xiàn)方式一樣,唯一不同的是 Listview 中沒有定義 android:layoutAnimation=”@anim/layout_animation”屬性,因為所有有關(guān) LayoutAnimation 的部分都是利用代碼來實現(xiàn)的; 最后我們來看看代碼(MyActivity.java)

public class MyActivity extends Activity {

    private ListView mListView;
    private ArrayAdapter mAdapter;

    private Button mAddListBtn;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mListView = (ListView) findViewById(R.id.listview);
        mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, getData());
        mListView.setAdapter(mAdapter);

        mAddListBtn = (Button)findViewById(R.id.addlist);
        mAddListBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mAdapter.addAll(getData());
            }
        });

        //代碼設(shè)置通過加載 XML 動畫設(shè)置文件來創(chuàng)建一個 Animation 對象;
        Animation animation= AnimationUtils.loadAnimation(this,R.anim.slide_in_left);   //得到一個 LayoutAnimationController 對象;
        LayoutAnimationController controller = new LayoutAnimationController(animation);   //設(shè)置控件顯示的順序;
        controller.setOrder(LayoutAnimationController.ORDER_REVERSE);   //設(shè)置控件顯示間隔時間;
        controller.setDelay(0.3f);   //為 ListView 設(shè)置 LayoutAnimationController 屬性;
        mListView.setLayoutAnimation(controller);
        mListView.startLayoutAnimation();
    }

    private List<String> getData() {

        List<String> data = new ArrayList<String>();
        data.add("測試數(shù)據(jù) 1");
        data.add("測試數(shù)據(jù) 2");
        data.add("測試數(shù)據(jù) 3");
        data.add("測試數(shù)據(jù) 4");

        return data;
    }
}

這段代碼中,在填充 listview 的代碼都是與 xml 的實現(xiàn)方式相同的,關(guān)鍵是填充后,開始給 listview 設(shè)置 LayoutAnimationController,代碼如下:

Animation animation= AnimationUtils.loadAnimation(this,R.anim.slide_in_left);   
//得到一個 LayoutAnimationController 對象;
LayoutAnimationController controller = new LayoutAnimationController(animation);   //設(shè)置控件顯示的順序;
controller.setOrder(LayoutAnimationController.ORDER_REVERSE);  
//設(shè)置控件顯示間隔時間;
controller.setDelay(0.3f);   
//為 ListView 設(shè)置 LayoutAnimationController 屬性;
mListView.setLayoutAnimation(controller);
mListView.startLayoutAnimation();

這段代碼就是構(gòu)造 LayoutAnimationController 變量,然后利用 setLayoutAnimation 將其設(shè)置為 listview,最后利用 mListView.startLayoutAnimation();開始動畫;難度不大,看一下就明白,沒必要細講了。 效果與上一部分 xml 實現(xiàn)一樣,就不再貼圖了 源碼在文章底部給出

三、GridLayoutAnimation 的 XML 實現(xiàn)——gridLayoutAnimation

1、概述

這部分將給大家講解有關(guān) gridview 給內(nèi)部子控件添加創(chuàng)建動畫的內(nèi)容。本部分的效果圖如下:

http://wiki.jikexueyuan.com/project/android-animation/images/116.gif" alt="" />

我們先來看一下 gridLayoutAnimation 標簽都有哪些屬性:

<?xml version="1.0" encoding="utf-8"?>
<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                     android:rowDelay="75%"
                     android:columnDelay="60%"
                     android:directionPriority="none"
                     android:direction="bottom_to_top|right_to_left"
                     android:animation="@android:anim/slide_in_left"/>

這是一個寫好了的 gridLayoutAnimation 的動畫文件。其中各字段的意義如下:

  • rowDelay:每一行動畫開始的延遲。與 LayoutAnimation 一樣,可以取百分數(shù),也可以取浮點數(shù)。取值意義為,當前 android:animation 所指動畫時長的倍數(shù)。
  • columnDelay:每一列動畫開始的延遲。取值類型及意義與 rowDelay 相同。
  • directionPriority:方向優(yōu)先級。取值為 row,collumn,none,意義分別為:行優(yōu)先,列優(yōu)先,和無優(yōu)先級(同時進行);具體意義,后面會細講
  • direction:gridview 動畫方向。 取值有四個:left_to_right:列,從左向右開始動畫 right_to_left :列,從右向左開始動畫 top_to_bottom:行,從上向下開始動畫 bottom_to_top:行,從下向上開始動畫 這四個值之間可以通過“|”連接,從而可以取多個值。很顯然 left_to_right 和 right_to_left 是互斥的,top_to_bottom 和 bottom_to_top 是互斥的。如果不指定 direction 字段,默認值為 left_to_right | top_to_bottom;即從上往下,從左往右。
  • animation: gridview 內(nèi)部元素所使用的動畫。

2、示例

上面,我們簡單講述了 gridLayoutAnimation 標簽各字段的意義,下面我們就構(gòu)建一個動畫,看看效果,這部分實現(xiàn)的效果如下:

http://wiki.jikexueyuan.com/project/android-animation/images/117.gif" alt="" />

第一:gridview 中各個元素的出場順序為從上往下,從左往右。 第二:gridLayoutAnimation 僅在 gridview 第一次創(chuàng)建時各個元素才會有出場動畫,在創(chuàng)建成功以后,再向其中添加數(shù)據(jù)就不會再有動畫。這一點與 layoutAnimation 相同。 下面來看看這個實例的實現(xiàn)過程: (1)、首先是 gride_animation.xml

<?xml version="1.0" encoding="utf-8"?>
<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                     android:rowDelay="75%"
                     android:columnDelay="60%"
                     android:directionPriority="none"
                     android:animation="@anim/slide_in_left"/>

這里沒有設(shè)置 android:direction 屬性,采用默認值:left_to_right|top_to_bottom;然后是對應的 animation 動畫 slide_in_left.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000">
    <translate android:fromXDelta="-50%p" android:toXDelta="0"/>
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0" />
</set>

與 LayoutAnimation 所使用的動畫一樣,也是從左側(cè) 50%的位置移動到初始位置,同時透明度從 0 變到 1; (2)、程序布局 main.xml 從效果圖中也可以很簡單的看出布局,布局很簡單,一個按鈕,一個 gridview,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <Button
            android:id="@+id/add_data"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="添加 grid 數(shù)據(jù)"/>

    <GridView
            android:id="@+id/grid"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:columnWidth="60dp"
            android:gravity="center"
            android:horizontalSpacing="10dp"
            android:layoutAnimation="@anim/gride_animation"
            android:numColumns="auto_fit"
            android:stretchMode="columnWidth"
            android:verticalSpacing="10dp"/>

</LinearLayout>

布局很簡單,就不再細講,這里最重要的部分,就是給 GridView 添加 android:layoutAnimation=”@anim/gride_animation”這句。以添加 gridLayoutAnimation。 下面看代碼處理部分 (3)、代碼處理 先貼出完整代碼,然后再細講:

public class MyActivity extends Activity {
    private GridAdapter mGrideAdapter;
    private List<String> mDatas = new ArrayList<>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        /**
         * 填充 gridview
         */
        GridView grid = (GridView) findViewById(R.id.grid);
        mDatas.addAll(getData());
        mGrideAdapter = new GridAdapter();
        grid.setAdapter(mGrideAdapter);

        /**
         * 按鈕點擊響應
         */
        Button addData = (Button)findViewById(R.id.add_data);
        addData.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addData();
            }
        });
    }

    private List<String> getData() {

        List<String> data = new ArrayList<String>();
        for (int i = 1;i<35;i++){
            data.add("DATA "+i);
        }
        return data;
    }

    public void addData(){
        mDatas.addAll(mDatas);
        mGrideAdapter.notifyDataSetChanged();
    }

    public class GridAdapter extends BaseAdapter {
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView i = new TextView(MyActivity.this);
            i.setText(mDatas.get(position));
            i.setLayoutParams(new GridView.LayoutParams(GridView.LayoutParams.WRAP_CONTENT, GridView.LayoutParams.WRAP_CONTENT));
            return i;
        }

        public final int getCount() {
            return mDatas.size();
        }

        public final Object getItem(int position) {
            return null;
        }

        public final long getItemId(int position) {
            return position;
        }
    }
}

這里主要是完成兩個功能,第一:填充 gridview 第二:在點擊按鈕的時候向 gridview 中新加數(shù)據(jù),看它是不是會有進入動畫。 先看第一部分:在 OnCreate 中

GridView grid = (GridView) findViewById(R.id.grid);
mDatas.addAll(getData());
mGrideAdapter = new GridAdapter();
grid.setAdapter(mGrideAdapter);

首先是構(gòu)造數(shù)據(jù)的函數(shù) getData():代碼如下,構(gòu)造出 35 個數(shù)據(jù)

private List<String> getData() {

    List<String> data = new ArrayList<String>();
    for (int i = 1;i<35;i++){
        data.add("DATA "+i);
    }
    return data;
}

然后是構(gòu)造 gridview 的 adapter 的構(gòu)造:

public class GridAdapter extends BaseAdapter {
    public View getView(int position, View convertView, ViewGroup parent) {
        TextView i = new TextView(MyActivity.this);
        i.setText(mDatas.get(position));
        i.setLayoutParams(new GridView.LayoutParams(GridView.LayoutParams.WRAP_CONTENT, GridView.LayoutParams.WRAP_CONTENT));
        return i;
    }

    public final int getCount() {
        return mDatas.size();
    }

    public final Object getItem(int position) {
        return null;
    }

    public final long getItemId(int position) {
        return position;
    }
}

在 getView 中,向每一個 item 填充一個 textview,將構(gòu)造的數(shù)據(jù) mDatas 所對應的 String 做為 textview 的內(nèi)容; 最后將 Adapter 設(shè)置給 gridview 就可以了:

grid.setAdapter(mGrideAdapter); 1 然后是第二部分,當點擊按鈕的時候,調(diào)用 addData()向其中添加數(shù)據(jù)

Button addData = (Button)findViewById(R.id.add_data);
addData.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        addData();
    }
});

其中 addData()的實現(xiàn)為:

public void addData(){
    mDatas.addAll(mDatas);
    mGrideAdapter.notifyDataSetChanged();
}

到這里,我這個例子就講完了,通過這個例子大家除了讓大家知道 gridLayoutAnimation 的使用方法以外,更要大家知道:gridLayoutAnimation 與 layoutAnimation 一樣,都只是在 viewGroup 創(chuàng)建的時候,會對其中的 item 添加進入動畫,在創(chuàng)建完成后,再添加數(shù)據(jù)將不會再有動畫! 通過上面的示例也可以看到,通過 xml 方式實現(xiàn) gradview 中 item 創(chuàng)建動畫是非常容易的,只需要在 gridview 的 xml 中添加 android:layoutAnimation="@anim/gride_animation"即可。不需要在代碼中做任何操作。 源碼在文章底部給出

3、gridLayoutAnimation 標簽各屬性詳解

在簡單看了上面的使用例子以后,我們就詳細來看看 gridLayoutAnimation 標簽各個屬性的意義吧。 有關(guān) rowDelay、columnDelay 和 animation 字段,想必大家也都已經(jīng)熟悉了,就不再講了,這里著重講一下 directionPriority 和 direction

(1)、directionPriority

directionPriority 指 gridview 動畫優(yōu)先級,取值有 row,column,none.意義分別為行優(yōu)先,列優(yōu)先,和無優(yōu)先級(同時進行)。 還以上面的例子為例,我們使用 direction 的默認值即 left_to_right|top_to_bottom,將 android:directionPriority 分別改變?yōu)?row,column,none,看它的效果如何。 android:directionPriority=”row” 對應的 gride_animation.xml 內(nèi)容為:

<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                     android:rowDelay="75%"
                     android:columnDelay="60%"
                     android:directionPriority="row"
                     android:animation="@anim/slide_in_left"/>

效果圖為:

http://wiki.jikexueyuan.com/project/android-animation/images/118.gif" alt="" />

從效果圖中可以看出,在優(yōu)先級改為行以后,gridview 中各個 item 的出場順序就變?yōu)橐恍幸恍械某霈F(xiàn)了。 android:directionPriority=”column” 對應的 gride_animation.xml 內(nèi)容為:

<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                     android:rowDelay="75%"
                     android:columnDelay="60%"
                     android:directionPriority="column"
                     android:animation="@anim/slide_in_left"/>

對應效果圖為:

http://wiki.jikexueyuan.com/project/android-animation/images/119.gif" alt="" />

從效果圖中可以看出,在優(yōu)先級改為列以后,gridview 中各個 item 的出場順序就改為一列一列的出現(xiàn)了。 android:directionPriority=”none” 對應的 gride_animation.xml 內(nèi)容為:

<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                     android:rowDelay="75%"
                     android:columnDelay="60%"
                     android:directionPriority="none"
                     android:animation="@anim/slide_in_left"/>

效果圖為:

http://wiki.jikexueyuan.com/project/android-animation/images/120.gif" alt="" />

從效果圖中可以看出,在優(yōu)先給改為 None 以后,gridview 中各個 item 的出場順序就是行,列一起進行了。 在知道優(yōu)先級字段的作用以后,我們來看看 android:direction 字段的意義

(2)、direction

direction 表示 gridview 的各個 item 的動畫方向,取值如下,可以通過“|”連接多個屬性值。 取值有四個:

  • left_to_right:列,從左向右開始動畫
  • right_to_left :列,從右向左開始動畫
  • top_to_bottom:行,從上向下開始動畫
  • bottom_to_top:行,從下向上開始動畫

為了更好的突顯效果,我們將 android:directionPriority 設(shè)置為 none 即行列一起進行動畫。 android:direction=”left_to_right”從左向右開始動畫 對應的 gride_animation.xml 內(nèi)容為:

<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                     android:rowDelay="75%"
                     android:columnDelay="60%"
                     android:directionPriority="none"
                     android:direction="left_to_right"
                     android:animation="@anim/slide_in_left"/>

效果圖為:

http://wiki.jikexueyuan.com/project/android-animation/images/121.gif" alt="" />

從效果圖中,很明顯可以看出,入場順序是從左向右的,由于上下的入場順序沒有指定,默認是從上向下入場 android:direction=”right_to_left”從右向左開始動畫 對應的 gride_animation.xml 內(nèi)容為:

<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                     android:rowDelay="75%"
                     android:columnDelay="60%"
                     android:directionPriority="none"
                     android:direction="right_to_left"
                     android:animation="@anim/slide_in_left"/>

效果圖為:

http://wiki.jikexueyuan.com/project/android-animation/images/122.gif" alt="" />

很明顯可以看出,各個 item 是從右向左入場的,同樣由于上下的入場順序沒有指定,默認是從上向下入場 android:direction=”top_to_bottom”從上向下開始動畫 對應的 gride_animation.xml 內(nèi)容為:

<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                     android:rowDelay="75%"
                     android:columnDelay="60%"
                     android:directionPriority="none"
                     android:direction="top_to_bottom"
                     android:animation="@anim/slide_in_left"/>

效果圖為:

http://wiki.jikexueyuan.com/project/android-animation/images/123.gif" alt="" />

從效果圖中可以看出,各個 item 是從上向下入場的。由于左右入場順序沒有指定,所以默認是從左向右入場。 android:direction=”bottom_to_top”從下向上開始動畫 對應的 gride_animation.xml 內(nèi)容為:

<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                     android:rowDelay="75%"
                     android:columnDelay="60%"
                     android:directionPriority="none"
                     android:direction="bottom_to_top"
                     android:animation="@anim/slide_in_left"/>

效果圖為:

http://wiki.jikexueyuan.com/project/android-animation/images/124.gif" alt="" />

從效果圖中可以看出,各個 item 是從下向上入場的。同樣由于左右入場順序沒有指定,所以默認是從左向右入場。 組合:android:direction=”bottom_to_top|right_to_left” 前面我們說過,可以通過”|”將多個屬性值連接起來,我們這里嘗試一下縱向從底向上入場,橫向從右向左入場。 對應的 gride_animation.xml 內(nèi)容為:

<gridLayoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
                     android:rowDelay="75%"
                     android:columnDelay="60%"
                     android:directionPriority="none"
                     android:direction="bottom_to_top|right_to_left"
                     android:animation="@anim/slide_in_left"/>

對應效果圖為:

http://wiki.jikexueyuan.com/project/android-animation/images/125.gif" alt="" />

從效果圖中明顯可以看出,我們實現(xiàn)了縱向從底向上入場,橫向從右向左入場的效果。 到這里,有關(guān) directionPriority 和 direction 各個取值的意義已經(jīng)講解完了,下面我們就來看看如何通過代碼來實現(xiàn) GridLayoutAnimation。

四、GridLayoutAnimation 的代碼實現(xiàn)——GridLayoutAnimationController

1、概述

我們知道 gridLayoutAnimation 標簽在代碼中對應 GridLayoutAnimationController 類,它的構(gòu)造方法如下:

public GridLayoutAnimationController(Animation animation)
public GridLayoutAnimationController(Animation animation, float columnDelay, float rowDelay)

其中 animation 對應標簽屬性中的 android:animation columnDelay 對應標簽屬性中的 android:columnDelay,取值為 float 類型 rowDelay 對應標簽屬性中的 android:rowDelay,取值為 float 類型 然后是 GridLayoutAnimationController 的幾個函數(shù):

/**
 * 設(shè)置列動畫開始延遲
 */
public void setColumnDelay(float columnDelay)
/**
 * 設(shè)置行動畫開始延遲
 */
 public void setRowDelay(float rowDelay)
 /**
 * 設(shè)置 gridview 動畫的入場方向。取值有:DIRECTION_BOTTOM_TO_TOP、DIRECTION_TOP_TO_BOTTOM、DIRECTION_LEFT_TO_RIGHT、DIRECTION_RIGHT_TO_LEFT
 */
 public void setDirection(int direction)
 /**
 * 動畫開始優(yōu)先級,取值有 PRIORITY_COLUMN、PRIORITY_NONE、PRIORITY_ROW
 */
 public void setDirectionPriority(int directionPriority)

這些函數(shù)和意義都與 xml 中的屬性相對應,這里就不再多講了,下面我們就來看看實例中的應用吧

2、示例

本部分將實現(xiàn)的效果圖如下:

http://wiki.jikexueyuan.com/project/android-animation/images/126.gif" alt="" />

與 xml 實現(xiàn)的效果類似,只是這里我們將不再寫 grideAnimation 的 xml 文件,而是完全通過代碼來構(gòu)造 grideAnimation。 無論怎樣,入場動畫還是需要的,所以我們同樣要創(chuàng)建一個 slide_in_left.xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000">
    <translate android:fromXDelta="-50%p" android:toXDelta="0"/>
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0" />
</set>

然后是布局文件 main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <GridView
            android:id="@+id/grid"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:columnWidth="60dp"
            android:gravity="center"
            android:horizontalSpacing="10dp"
            android:numColumns="auto_fit"
            android:stretchMode="columnWidth"
            android:verticalSpacing="10dp"/>

</LinearLayout>

最后是 MyActivity 中的填充部分:

public class MyActivity extends Activity {
    private GridAdapter mGrideAdapter;
    private List<String> mDatas = new ArrayList<>();
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        /**
         * 填充 gridview
         */
        GridView grid = (GridView) findViewById(R.id.grid);
        mDatas.addAll(getData());
        mGrideAdapter = new GridAdapter();
        grid.setAdapter(mGrideAdapter);

        Animation animation = AnimationUtils.loadAnimation(MyActivity.this,R.anim.slide_in_left);
        GridLayoutAnimationController controller = new GridLayoutAnimationController(animation);
        controller.setColumnDelay(0.75f);
        controller.setRowDelay(0.5f);
        controller.setDirection(GridLayoutAnimationController.DIRECTION_BOTTOM_TO_TOP|GridLayoutAnimationController.DIRECTION_LEFT_TO_RIGHT);
        controller.setDirectionPriority(GridLayoutAnimationController.PRIORITY_NONE);
        grid.setLayoutAnimation(controller);
        grid.startLayoutAnimation();
    }

    private List<String> getData() {

        List<String> data = new ArrayList<String>();
        for (int i = 1;i<35;i++){
            data.add("DATA "+i);
        }
        return data;
    }

    public void addData(){
        mDatas.addAll(mDatas);
        mGrideAdapter.notifyDataSetChanged();
    }

    public class GridAdapter extends BaseAdapter {
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView i = new TextView(MyActivity.this);
            i.setText(mDatas.get(position));
            i.setLayoutParams(new GridView.LayoutParams(GridView.LayoutParams.WRAP_CONTENT, GridView.LayoutParams.WRAP_CONTENT));
            return i;
        }

        public final int getCount() {
            return mDatas.size();
        }

        public final Object getItem(int position) {
            return null;
        }

        public final long getItemId(int position) {
            return position;
        }
    }
}

這部分代碼雖然比較長,但填充 grideView 部分與上段實現(xiàn)是一致的。唯一不同的就是設(shè)置 GridLayoutAnimationController 的部分:

Animation animation = AnimationUtils.loadAnimation(MyActivity.this,R.anim.slide_in_left);
GridLayoutAnimationController controller = new GridLayoutAnimationController(animation);
controller.setColumnDelay(0.75f);
controller.setRowDelay(0.5f);
controller.setDirection(GridLayoutAnimationController.DIRECTION_BOTTOM_TO_TOP|GridLayoutAnimationController.DIRECTION_LEFT_TO_RIGHT);
controller.setDirectionPriority(GridLayoutAnimationController.PRIORITY_NONE);
grid.setLayoutAnimation(controller);
grid.startLayoutAnimation();

這部分理解起來難度也不大,無外乎就是構(gòu)造一個 GridLayoutAnimationController,然后通過它的各個 set 函數(shù)把各個屬性值設(shè)置進去。 源碼在文章底部給出 到這里有關(guān) LayoutAnimationt 和 GridLayoutAnimation 的部分就講完了,下面對他們的特性做一個總結(jié)。

總結(jié): 1、LayoutAnimationt 和 GridLayoutAnimation 是在 api1 時就已經(jīng)引入進來了,所以不用擔心 API 不支持的問題 2、gridLayoutAnimation 與 layoutAnimation 一樣,都只是在 viewGroup 創(chuàng)建的時候,會對其中的 item 添加進入動畫,在創(chuàng)建完成后,再添加數(shù)據(jù)將不會再有動畫! 3、LayoutAnimationt 和 GridLayoutAnimation 僅支持 Animation 動畫,不支持 Animator 動畫;正是因為它們在 api 1 就引入進來了,而 Animator 是在 API 11 才引入的,所以它們是不可能支持 Animator 動畫的。 這篇文章到這里就結(jié)束了,這篇文章實現(xiàn)的效果只有在初次創(chuàng)建時才會有動畫,下篇將給大家講解如何在運行中給 viewGroup 中的 item 使用進入退出動畫。

源碼內(nèi)容: 1、《BlogLayoutAnimation》:第一部分,LayoutAnimation xml 實現(xiàn)與代碼實現(xiàn)所對應的代碼 2、《BlogGrideAnimation》:第二部分的第一段,GrideAnimation 的 xml 實現(xiàn)所對應的代碼 3、《BlogGridAnimationJava》:第二部分的第二段,GrideAnimation 的 JAVA 實現(xiàn)所對應的代碼。

如果本文有幫到你,記得加關(guān)注哦 源碼下載地址:http://download.csdn.net/detail/harvic880925/9451324 請大家尊重原創(chuàng)者版權(quán),轉(zhuǎn)載請標明出處:http://blog.csdn.net/harvic880925/article/details/50785786 謝謝