高仿QQ的手機管家的小火箭加速

1、前言

相信很多人都用過騰訊的手機管家,用過這個App的人都應該知道桌面的火箭一鍵加速這個功能,當然這裏我不是推薦大家去使用手機管家,相反這個功能大家還是小心爲妙,我的U8800加完速之後快是快了,但這傢伙把我手機的任務欄的進程都給搞蹦死了,去年買了個表啊。。。

吐槽不多說,來正題,最近剛好在學UI設計就去研究一下這個小火箭是怎麼做出來的。先來了解一下小火箭有神馬動作先,首先在沒有觸碰它時,就是一個電源的顯示或是

一個圖標依附在屏幕的兩側,點擊變成小火箭,可以跟隨拖動,當沒有放到指定位置就在次回去屏幕兩側。當放到了指定位置就會出現一個火箭發射的動畫。瞭解完效果,我

們繼續說。

2、完成的效果圖


3、簡單設計過程

自定義一個View完成火箭的拖動、顯示,然後拖動到指定位置後就回調一個接口播放火箭發射動畫。自定義View裏面的關鍵就是動態的改變matrix,以達到火箭移動的效果

4、核心代碼

自定義View的代碼

package com.spring.lettel;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;


/**
 * 火箭主體類
 * @author wissea
 *
 */
public class Rocket extends View {

	private Bitmap bitmap;
	private Bitmap rocket;
	//文字欄的三種狀態
	private Bitmap[] stand = {
			BitmapFactory.decodeResource(getResources(),
					R.drawable.desktop_bg_tips_1),
			BitmapFactory.decodeResource(getResources(),
					R.drawable.desktop_bg_tips_2),
			BitmapFactory.decodeResource(getResources(),
					R.drawable.desktop_bg_tips_3) };
	private Matrix matrix = new Matrix();
	private Paint paint = new Paint();

	// 是否觸摸
	private boolean isTouch = false;
	private Point point = new Point();

	private LocationChangeListener changeListener	=null;
	//記錄屏幕的大小
	private int screenW;
	private int screenH;

	//灰機和提示是否重合了
	private boolean isFly = false;

	public Rocket(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public Rocket(Context context, AttributeSet attrs) {
		super(context, attrs);
		bitmap = BitmapFactory.decodeResource(getResources(),
				R.drawable.floating_desktop_bg_danger);
		rocket = BitmapFactory.decodeResource(getResources(),
				R.drawable.desktop_rocket_launch_1);
		screenW = ((Activity) context).getWindowManager().getDefaultDisplay()
				.getWidth();
		screenH = ((Activity) context).getWindowManager().getDefaultDisplay()
				.getHeight();
	}

	public Rocket(Context context) {
		super(context);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		//判斷Touch
		if (!isTouch) {
			matrix.reset();
			if (isFly) {
				if(changeListener!=null)
					changeListener.onchange();
			} else {
				if (point.x < screenW / 2) {
					matrix.postTranslate(0, point.y);
				} else {
					matrix.postTranslate(screenW - bitmap.getWidth(), point.y);
				}
				canvas.drawBitmap(bitmap, matrix, paint);
			}
		} else {
			matrix.reset();
			int c = point.x % 2;
			matrix.postTranslate(screenW / 2 - stand[c].getWidth() / 2, screenH
					- stand[c].getHeight() - 100);
			//判斷重合
			if (Math.abs(screenW / 2 - (point.x - rocket.getWidth()/2)) < stand[c]
					.getWidth() / 2
					&& Math.abs(screenH - stand[c].getHeight() - 100
							- (point.y - rocket.getHeight())) < stand[c]
								.getHeight()) {
				canvas.drawBitmap(stand[2], matrix, paint);
				isFly = true;
			} else {
				isFly		=false;
				canvas.drawBitmap(stand[c], matrix, paint);
			}
			matrix.reset();
			matrix.postTranslate(point.x - rocket.getWidth()/2,
					point.y - rocket.getHeight());
			canvas.drawBitmap(rocket, matrix, paint);
		}

	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			//過濾無效點擊
			if ((event.getX() < screenW - bitmap.getWidth() && event.getX() > bitmap
					.getWidth())
					|| Math.abs(point.y - event.getY()) > bitmap.getHeight()) {
				return false;
			}
			isTouch = true;
			break;
		case MotionEvent.ACTION_MOVE:
			//更新座標
			point.x = (int) event.getX();
			point.y = (int) event.getY();
			break;
		case MotionEvent.ACTION_CANCEL:
			isTouch = false;
			break;
		case MotionEvent.ACTION_UP:
			isTouch = false;
			break;
		}
		invalidate();
		return true;
	}
	//重置狀態
	public void reset(){
		isFly	=false;
		point.y		=screenH/2;
		invalidate();
	}
	//監聽重合
	public void setOnChangeListener(LocationChangeListener changeListener){
		this.changeListener			=changeListener;
	}

}

5、總結

這個UI製作的時候老是糾結於,在View裏面播放動畫,找了老半天沒有找到解決方法,最後就把動畫放到了外面回調一下,雖然大體的效果出來了,但個人覺得還是有

不完善的地方,比如發射動畫不是很平滑,沒有加入電量顯示,沒有控制邊界,小火箭拉到屏幕外後就看不到控制的小圓點了。最後歡迎大家的討論,和指點。



有些同學反映飛不起來,可能是版本問題2.3有些Api跟4.0不一樣導致的,這個是用4.0開發的。

有時間在補上這個問題

項目源碼


5、廣告

      最近搞了個微信公衆號,爲各種程序員枯燥的寫碼生活添加一些生活調料,

      在等待編譯的過程看一篇美麗的圖文放鬆放鬆肌肉。希望各位看官賞臉關注一下

      公衆號:馬桶上的哲學

      讀哲名理,提升逼格


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章