本文完整項(xiàng)目代碼敬請(qǐng)見GitHub
app加載中狀態(tài),有圖片上下跳動(dòng),并每跳一次換一張圖片
首先準(zhǔn)備幾張圖片
思路
這個(gè)控件應(yīng)該派生自ImageView類,這樣才能方便地更改它的源文件內(nèi)容;
實(shí)現(xiàn)上下移動(dòng)的效果:
利用ValueAnimator實(shí)時(shí)產(chǎn)生一個(gè)0~100的數(shù)值倍试,
讓當(dāng)前圖片的位置實(shí)時(shí)向上移動(dòng)ValueAnimator的動(dòng)態(tài)值的高度即可。要讓圖片的位置實(shí)時(shí)向上移動(dòng)蛋哭,
就需要先拿到初始狀態(tài)下圖片的位置易猫。
每次控件被布局時(shí)
都會(huì)調(diào)用
onLayout(boolean changed,int left具壮,int top准颓,int right,int bottom)
函數(shù)棺妓,
其中的參數(shù)left攘已、top、right怜跑、bottom就是當(dāng)前控件的位置样勃。
通過重寫onLayout()
函數(shù),我們可以拿到控件的初始高度mTop
性芬,
之后在每次ValueAnimator的動(dòng)態(tài)值到來(lái)時(shí)峡眶,
計(jì)算出當(dāng)前控件的top位置,并將控件移動(dòng)到這個(gè)位置就可以了植锉。
實(shí)現(xiàn)
自定義一個(gè)控件LoadingImageView辫樱,派生自ImageView,
重寫onLayout()函數(shù)俊庇,拿到控件的初始top值
(onLayout()
函數(shù)只在一開始創(chuàng)建Activity的時(shí)候調(diào)用了一次而已狮暑,
后面我們是通過ValueAnimator
來(lái)改變高度值,
沒有調(diào)用到onLayout()
函數(shù))init() 函數(shù)中辉饱,創(chuàng)建并初始化ValueAnimator實(shí)例:
通過(mTop-dx)得到當(dāng)前控件相對(duì)初始坐標(biāo)上移dx距離后的最新坐標(biāo)點(diǎn)搬男;
通過setTop(int top)函數(shù)將控件移動(dòng)到當(dāng)前位置。getTop()和setTop(int top)函數(shù)所得到的和設(shè)置的坐標(biāo)
都是相對(duì)父控件的坐標(biāo)位置彭沼。監(jiān)聽動(dòng)畫的開始和重復(fù)缔逛。
當(dāng)動(dòng)畫開始時(shí),圖片設(shè)置為imagetest1.jpg;
在重復(fù)時(shí)褐奴,每重復(fù)一次更換一張圖片按脚。
public class LoadingImageView extends ImageView {
private int mTop;
//當(dāng)前動(dòng)畫圖片索引
private int mCurImgIndex = 0;
//動(dòng)畫圖片總張數(shù)
private static int mImgCount = 3;
public LoadingImageView(Context context) {
super(context);
init();
}
public LoadingImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public LoadingImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
mTop = top;
}
private void init() {
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 100, 0);
valueAnimator.setRepeatCount(valueAnimator.RESTART);
valueAnimator.setRepeatCount(valueAnimator.INFINITE);
valueAnimator.setDuration(2000);
valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
Integer dx = (Integer) animation.getAnimatedValue();
setTop(mTop - dx);
}
});
valueAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
setImageDrawable(getResources(). getDrawable(R.drawable.imagetest1));
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
mCurImgIndex++;
switch (mCurImgIndex % mImgCount) {
case 0:
setImageDrawable(getResources(). getDrawable(R.drawable.imagetest1));
break;
case 1:
setImageDrawable(getResources(). getDrawable(R.drawable.imagetest2));
break;
case 2:
setImageDrawable(getResources(). getDrawable(R.drawable.imagetest3));
break;
}
}
});
valueAnimator.start();
}
}
- 使用控件并運(yùn)行
case 5:
LoadingImageView loadingImageView = new LoadingImageView(this);
ll_nextParent.addView(loadingImageView, layoutParams);
break;
- 完整項(xiàng)目代碼敬請(qǐng)見GitHub