編輯:關於Android編程
熟悉了基礎動畫的實現後,便可以試著去實現常見APP中出現過的那些精美的動畫。今天我主要給大家引入一個APP的ListView的動畫效果: 當展示ListView時,Listview的每一個列表項都按照規定的動畫顯示出來。
說起來比較抽象,先給大家看一個動畫效果,這是APP窩牛裝修的ListView顯示動畫:

有木有覺得很酷炫?有木有啊!?
一、Layout Animation
所謂的布局動畫,其實就是為ViewGroup添加顯示動畫效果,主要用過LayoutAnimationController來控制實現。LayoutAnimationController用於為一個Layout裡面的控件,或者是一個ViewGroup裡面的控件設置動畫效果,可以在XML文件中設置,亦可以在Java代碼中設置。
1.1 在XML文件中設置布局動畫
首先,我們在res/anim文件夾下建立一個list_anim_layout.xml文件,該文件就是布局動畫控制器。
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android" android:delay="30%" android:animationOrder="random" android:animation="@anim/slide_right" />
android:delay 子類動畫時間間隔 (延遲) 70% 也可以是一個浮點數 如“1.2”等。
android:animationOrder="random" 子類的顯示方式 random表示隨機。
android:animationOrder 的取值有
android:animation="@anim/slide_right" 表示列表項顯示時的具體動畫是什麼!
下面,我們定義每一個列表項顯示時的動畫效果吧,及slide_right.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<translate
android:duration="3000"
android:fromXDelta="100%p"
android:toXDelta="0%p" />
</set>
顯示的效果為ListView第一次出現的時候為 item隨機出現 每個Item都是從右邊的區域向左滑動到顯示的地方。
接下來,你只需要把這個布局動畫,指定到ViewGroup上就好了:
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/list_anim_layout"
>
</ListView>
就這麼簡單就完成了,快來看下效果吧:

1.2 在Java代碼中實現布局動畫
在Java代碼中實現布局動畫並無難度,只要熟悉幾個API的使用即可。 關於動畫的定義和上文一致,只是,你不需要再在把控制動畫應用到listview中了,即android:layoutAnimation="@anim/list_anim_layout"這行代碼可以刪除。
接下來,需要在Java代碼中進行配置:
private void startLayoutAnim() {
//通過加載XML動畫設置文件來創建一個Animation對象;
Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_right);
//得到一個LayoutAnimationController對象;
LayoutAnimationController lac = new LayoutAnimationController(animation);
//設置控件顯示的順序;
lac.setOrder(LayoutAnimationController.ORDER_REVERSE);
//設置控件顯示間隔時間;
lac.setDelay(1);
//為ListView設置LayoutAnimationController屬性;
listView.setLayoutAnimation(lac);
}
觀察下,效果和之前使用xml文件肯定是一致的了。
介紹到這裡,可能有人會有疑問了,博文一開始介紹的“窩牛裝修”的那種效果,是每一個列表項顯示的時候才會顯示動畫。我們這個確實所有的列表項的動畫一起都顯示了,只是顯示順序不同而已。 通過我們這種方法,怎麼可能會達到那種效果呢?
確實,通過布局動畫,沒辦法控制每一個Item在加載時才顯示動畫。那該如何是好呢?
兄弟們,換個思路吧,如果布局動畫完成不了,何必不直接用簡單的補間動畫,再結合每個列表項的顯示控制,來實現窩牛裝修列表顯示的效果呢?
那有人會問了,怎麼知道每一個列表項何時才加載麼?
你難道忘了BaseAdapter的getView()方法了麼?
沒錯,每當一個列表項顯示時,都會主動調用BaseAdaper的getView()方法。
二、仿窩牛裝修List列表的動畫效果
首先,我們定義一個動畫資源,該動畫即是列表項顯示時的動畫:woniu_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
>
<!-- woniu list item animation -->
<translate
android:duration="500"
android:fromXDelta="0"
android:fromYDelta="100"
android:toXDelta="0"
android:toYDelta="0" />
</set>
該平移動畫表示,從下往上,垂直平移100px,時間為500毫秒。
接下來,我們需要在BaseAdapter的getView()方法裡,去使用該動畫:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class WoniuListAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mInflater;
private List<WoniuSimple> mDatas;
private Animation animation;
public WoniuListAdapter(Context context, List<WoniuSimple> datas) {
mContext = context;
mInflater = LayoutInflater.from(mContext);
mDatas = datas;
animation = AnimationUtils.loadAnimation(mContext, R.anim.woniu_list_item);
}
@Override
public int getCount() {
return (mDatas != null ? mDatas.size() : 0);
}
@Override
public Object getItem(int position) {
return (mDatas != null ? mDatas.get(position) : null);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) {
// 下拉項布局
convertView = mInflater.inflate(R.layout.list_item_woniu, null);
holder = new ViewHolder();
holder.tem_img = (ImageView) convertView.findViewById(R.id.tem_img);
holder.text_name = (TextView) convertView.findViewById(R.id.text_name);
holder.text_name = (TextView) convertView.findViewById(R.id.text_name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
convertView.startAnimation(animation);
final WoniuSimple materialSimple = mDatas.get(position);
if (materialSimple != null) {
// holder.tem_img.setImageResource(R.mipmap.assist_default_img);
// holder.text_name.setText(materialSimple.name);
// holder.text_mobile.setText(materialSimple.mobile);
}
return convertView;
}
class ViewHolder {
ImageView tem_img;
TextView text_name;
TextView text_mobile;
}
}
我們來簡要分析應用動畫的地方: 1、我們Adapter的構造方法裡加載了之前定義的動畫,活的Animation對象。 2、 我們在getView方法裡,為convertView設置並啟動Animation,即convertView.startAnimation(animation)。
夠簡單吧,只是這麼兩行代碼,就可以實現在加載每一個View Item時啟動動畫效果。
可是,我們發現,這並不是非常完美的實現,為啥這麼說呢?
因為你此刻往上滑動列表,會發現,已經加載過的Item的動畫還會再次啟動執行一次。這個體驗太糟糕了。為啥會出現這種情況啊?
因為getVIew方法的調用時機會對動畫產生影響。Adapter中的getView方法,會在每一個item處於可見狀態時調用,所以無論你上滑還是下滑,都會重復調用getView方法(這也是ListView為啥在使用時要進行優化的地方)。
所以,為了解決剛剛發生的問題,我們可以設置標識,進行判斷,已經加載過的view的動畫不再進行啟動加載。
完整的代碼如下:
package com.lnyp.layoutanimation;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class WoniuListAdapter extends BaseAdapter {
private Context mContext;
private LayoutInflater mInflater;
private List<WoniuSimple> mDatas;
private Animation animation;
private Map<Integer, Boolean> isFrist;
public WoniuListAdapter(Context context, List<WoniuSimple> datas) {
mContext = context;
mInflater = LayoutInflater.from(mContext);
mDatas = datas;
animation = AnimationUtils.loadAnimation(mContext, R.anim.woniu_list_item);
isFrist = new HashMap<Integer, Boolean>();
}
@Override
public int getCount() {
return (mDatas != null ? mDatas.size() : 0);
}
@Override
public Object getItem(int position) {
return (mDatas != null ? mDatas.get(position) : null);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
int type = getItemViewType(position);
if (convertView == null) {
// 下拉項布局
convertView = mInflater.inflate(R.layout.list_item_woniu, null);
holder = new ViewHolder();
holder.tem_img = (ImageView) convertView.findViewById(R.id.tem_img);
holder.text_name = (TextView) convertView.findViewById(R.id.text_name);
holder.text_name = (TextView) convertView.findViewById(R.id.text_name);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
// 如果是第一次加載該view,則使用動畫
if (isFrist.get(position) == null || isFrist.get(position)) {
convertView.startAnimation(animation);
isFrist.put(position, false);
}
final WoniuSimple materialSimple = mDatas.get(position);
if (materialSimple != null) {
// holder.tem_img.setImageResource(R.mipmap.assist_default_img);
// holder.text_name.setText(materialSimple.name);
// holder.text_mobile.setText(materialSimple.mobile);
}
return convertView;
}
class ViewHolder {
ImageView tem_img;
TextView text_name;
TextView text_mobile;
}
}
看到了麼,加了一個isFirst進行判斷,這樣,就可以有效控制動畫的顯示了。效果如下:

本文我主要介紹了兩個部分,一個是Layout Animation布局動畫,使用布局動畫可以控制VIew Groups中的每一個數據的顯示動畫; 還一個就是實戰,仿“窩牛裝修”ListView滑動時每一個Item滑動進入可見狀態的動畫效果。通過這兩個動畫示例,我相信可以幫助大家更好的處理動畫,克服“動畫恐懼症”。
希望本文所述對大家學習有所幫助,大家也會喜歡,小編一定會再接再厲,為大家分享更多精彩的文章。
紅米note4什麼時候上市?紅米Note4真機疑曝光
前兩天,一張小米的宣傳海報在網上曝光,海報中是小米剛簽下的紅米代言人之一劉昊然,而亮點在於他手中的手機,這部手機采用了雙攝像頭設計,應該是一部還未發布的紅米
手機迅雷個人中心關閉朋友圈方法
1、打開手機迅雷點擊切換到我的迅雷個人中心,點擊左上角[登錄],已登錄請跳過2、在手機迅雷個人中心的最下面,倒數第二項[常用設置]點擊進行設置3、繼續在常用
學習JNI--Android下使用JNI調用C
一、什麼是JNI: JNI是Java Native Interface的縮寫,中文為JAVA本地調用。從Java1.1開始,Java Native Interface
Android中AlertDialog的六種創建方式
創建AlertDialog的步驟: 1、創建AlertDialog.Builder對象 2、調用Builder對象的setTitle方法設置標題,setI