天天看點

學習自定義View(二)仿58同城加載

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

先看效果圖:

學習自定義View(二)仿58同城加載

 錄制的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形狀切換方式不夠優雅~ 增加一些自定義屬性 之類的......