之前用58同城app的時候看到它的加載界面不錯,但是那時候還不知道如何實作~接觸自定義View後,于是自己試着模仿寫了一個
先看效果圖:

錄制的GIF上有一點卡,其實在真機上面運作很流暢的~
其實感覺實作起來并不難,下面說下我的思路,首先是三個形狀: 圓、三角、矩形,然後使用動畫讓它平移達到上升下落的效果,恩差不多~ 開搞
首先在ondraw()開始畫
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
cx = getWidth() / 2;
cy = getHeight() / 2;
switch (type) {
case 1:
// 畫圓
mPaint.setColor(Color.RED);
canvas.drawCircle(cx, cy, mRadius, mPaint);
break;
case 2:
// 畫三角形
mPath.moveTo(cx, cy - mRadius);
mPath.lineTo(cx + mRadius, cy + mRadius);
mPath.lineTo(cx - mRadius, cy + mRadius);
mPaint.setColor(Color.GREEN);
mPath.close();
canvas.drawPath(mPath, mPaint);
break;
case 3:
// 畫正方形
RectF.set(cx - mRadius, cy - mRadius, cx + mRadius, cy + mRadius);
mPaint.setColor(Color.YELLOW);
canvas.drawRect(RectF, mPaint);
break;
default:
break;
}
}
是不是很簡單啊~ 根據不同的類型畫不同的形狀(PS:三角形其實沒有畫好.....數死早)~ 然後傳入不同的type畫不同的形狀,不就實作形狀的變換了嘛~ 哦也 第一步完成
但是注意,View隻是原地在變換,我們要它動起來!,我這裡用動畫實作~
public void moveBottom() {
ObjectAnimator animator = ObjectAnimator.ofFloat(this, "translationY",
0, 0 + mBounceHeight);
ObjectAnimator objectAnimator1 = null;
switch (type) {
case 1:// 圓形其實不需要旋轉
objectAnimator1 = ObjectAnimator.ofFloat(this, "rotation", 0, -0);
break;
case 2:// 如果是三角形下落旋轉120度
objectAnimator1 = ObjectAnimator.ofFloat(this, "rotation", 0, -120);
break;
case 3:// 如果是正方形下落就旋轉 90度
objectAnimator1 = ObjectAnimator.ofFloat(this, "rotation", 0, -90);
break;
default:
break;
}
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animator, objectAnimator1);
animatorSet.setDuration(mDuration);
animatorSet.setInterpolator(new AccelerateInterpolator());// 加速
animatorSet.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
moveTop();
if (type == 1) {
scale1();
}
}
@Override
public void onAnimationCancel(Animator animation) {
}
});
animatorSet.start();
}
這裡是屬性動畫~ View向下移動,且加速,移動的同時并且旋轉根據不同的類型旋轉不同的角度,在動畫執行後,再執行平移向上
public void moveTop() {
ObjectAnimator animator = ObjectAnimator.ofFloat(this, "translationY",
mBounceHeight, 0);
ObjectAnimator objectAnimator1 = null;
switch (type) {
case 1:// 圓形其實不需要旋轉
objectAnimator1 = ObjectAnimator.ofFloat(this, "rotation", 0, -0);
break;
case 2:// 如果是三角形下落旋轉120度
objectAnimator1 = ObjectAnimator.ofFloat(this, "rotation", 0, -120);
break;
case 3:// 如果是正方形下落就旋轉 90度
objectAnimator1 = ObjectAnimator.ofFloat(this, "rotation", 0, -90);
break;
default:
break;
}
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(animator, objectAnimator1);
animatorSet.setDuration(mDuration);
animatorSet.setInterpolator(new DecelerateInterpolator());// 減速
animatorSet.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
type++;
if (type > 3) {
type = 1;
}
moveBottom();
invalidate();
}
public void onAnimationCancel(Animator animation) {
}
});
animatorSet.start();
}
這個和上面那個差不多,就是執行完之後 換一種Type調用invaludate重新整理onDraw方法換一種形狀,然後 再執行落下的動畫,這就實作了View不斷落下升起的效果~
細心的朋友注意到下面那個陰影了,這是怎麼實作的呢? 很簡單 在球下面放一個ImageView,給一張背景圖檔,然後執行 縮放動畫 X方向(注意:要和View下落和上升儲存同步)
ObjectAnimator scaleIndication = ObjectAnimator.ofFloat(mImageView,
"scaleX", 0.5F, 1.5f);
scaleIndication.setDuration(MyProgressView.mDuration);
scaleIndication.start();
scaleIndication.setInterpolator(new AccelerateInterpolator());
scaleIndication.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
public void onAnimationRepeat(Animator animation) {
}
public void onAnimationEnd(Animator animation) {
scale1();
}
public void onAnimationCancel(Animator animation) {
}
});
這個是變大,還有一個變小的代碼就不貼了,參數換一下就行了,到這裡實作的就差不多了~ 有興趣的同學可以自己試下
是不是很簡單啊~ 不過自己覺得還有一些改進的地方,View形狀切換方式不夠優雅~ 增加一些自定義屬性 之類的......