生活随笔
收集整理的這篇文章主要介紹了
Android桌面悬浮窗进阶,QQ手机管家小火箭效果实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這次我們將代碼的重點放在火箭升空的效果上,因此簡單起見,就直接在模仿360手機衛士懸浮窗的那份代碼的基礎上繼續開發了,如果你還沒有看過那篇文章的話,建議先去閱讀?Android桌面懸浮窗效果實現,仿360手機衛士懸浮窗效果?。
比起普通的桌面懸浮窗,現在我們需要在拖動懸浮窗的時候將懸浮窗變成一個小火箭,并且在屏幕的底部添加一個火箭發射臺。那么我們就從火箭發射臺開始編寫吧,首先創建launcher.xml作為火箭發射臺的布局文件,如下所示:
[html]?view plaincopy
<?xml?version="1.0"?encoding="UTF-8"?>?? <LinearLayout?? ????xmlns:android="http://schemas.android.com/apk/res/android"?? ????android:layout_width="wrap_content"?? ????android:layout_height="wrap_content"?? ????android:orientation="vertical"?? ????>?? ?????? ????<ImageView??? ????????android:id="@+id/launcher_img"?? ????????android:layout_width="200dp"?? ????????android:layout_height="88dp"?? ????????android:src="@drawable/launcher_bg_hold"?? ????????/>?? ?????? </LinearLayout>??
可以看到,這里的ImageView是用于顯示當前火箭發射臺狀態的。我事先準備好了兩張圖片,一張是當小火箭未拖動到火箭發射臺時顯示的,一張是當小火箭拖動到火箭發射臺上時顯示的。
接下來創建RocketLauncher類,作為火箭發射臺的View,代碼如下所示:
[java] view plaincopy
public?class?RocketLauncher?extends?LinearLayout?{????????????????public?static?int?width;????????????????public?static?int?height;????????????????private?ImageView?launcherImg;????????public?RocketLauncher(Context?context)?{??????????super(context);??????????LayoutInflater.from(context).inflate(R.layout.launcher,?this);??????????launcherImg?=?(ImageView)?findViewById(R.id.launcher_img);??????????width?=?launcherImg.getLayoutParams().width;??????????height?=?launcherImg.getLayoutParams().height;??????}????????????????public?void?updateLauncherStatus(boolean?isReadyToLaunch)?{??????????if?(isReadyToLaunch)?{??????????????launcherImg.setImageResource(R.drawable.launcher_bg_fire);??????????}?else?{??????????????launcherImg.setImageResource(R.drawable.launcher_bg_hold);??????????}??????}????}??
RocketLauncher中的代碼還是非常簡單的,在構建方法中調用了LayoutInflater的inflate()方法來將launcher.xml這個布局文件加載進來,并獲取到了當前View的寬度和高度。在updateLauncherStatus()方法中會進行判斷,如果傳入的參數是true,就顯示小火箭即將發射的圖片,如果傳入的是false,就顯示將小火箭拖動到發射臺的圖片。
新增的文件只有這兩個,剩下的就是要修改之前的代碼了。首先修改MyWindowManager中的代碼,如下所示:
[java] view plaincopy
public?class?MyWindowManager?{????????????????private?static?FloatWindowSmallView?smallWindow;????????????????private?static?FloatWindowBigView?bigWindow;????????????????private?static?RocketLauncher?rocketLauncher;????????????????private?static?LayoutParams?smallWindowParams;????????????????private?static?LayoutParams?bigWindowParams;????????????????private?static?LayoutParams?launcherParams;????????????????private?static?WindowManager?mWindowManager;????????????????private?static?ActivityManager?mActivityManager;????????????????public?static?void?createSmallWindow(Context?context)?{??????????WindowManager?windowManager?=?getWindowManager(context);??????????int?screenWidth?=?windowManager.getDefaultDisplay().getWidth();??????????int?screenHeight?=?windowManager.getDefaultDisplay().getHeight();??????????if?(smallWindow?==?null)?{??????????????smallWindow?=?new?FloatWindowSmallView(context);??????????????if?(smallWindowParams?==?null)?{??????????????????smallWindowParams?=?new?LayoutParams();??????????????????smallWindowParams.type?=?LayoutParams.TYPE_SYSTEM_ALERT;??????????????????smallWindowParams.format?=?PixelFormat.RGBA_8888;??????????????????smallWindowParams.flags?=?LayoutParams.FLAG_NOT_TOUCH_MODAL??????????????????????????|?LayoutParams.FLAG_NOT_FOCUSABLE;??????????????????smallWindowParams.gravity?=?Gravity.LEFT?|?Gravity.TOP;??????????????????smallWindowParams.width?=?FloatWindowSmallView.windowViewWidth;??????????????????smallWindowParams.height?=?FloatWindowSmallView.windowViewHeight;??????????????????smallWindowParams.x?=?screenWidth;??????????????????smallWindowParams.y?=?screenHeight?/?2;??????????????}??????????????smallWindow.setParams(smallWindowParams);??????????????windowManager.addView(smallWindow,?smallWindowParams);??????????}??????}????????????????public?static?void?removeSmallWindow(Context?context)?{??????????if?(smallWindow?!=?null)?{??????????????WindowManager?windowManager?=?getWindowManager(context);??????????????windowManager.removeView(smallWindow);??????????????smallWindow?=?null;??????????}??????}????????????????public?static?void?createBigWindow(Context?context)?{??????????WindowManager?windowManager?=?getWindowManager(context);??????????int?screenWidth?=?windowManager.getDefaultDisplay().getWidth();??????????int?screenHeight?=?windowManager.getDefaultDisplay().getHeight();??????????if?(bigWindow?==?null)?{??????????????bigWindow?=?new?FloatWindowBigView(context);??????????????if?(bigWindowParams?==?null)?{??????????????????bigWindowParams?=?new?LayoutParams();??????????????????bigWindowParams.x?=?screenWidth?/?2??????????????????????????-?FloatWindowBigView.viewWidth?/?2;??????????????????bigWindowParams.y?=?screenHeight?/?2??????????????????????????-?FloatWindowBigView.viewHeight?/?2;??????????????????bigWindowParams.type?=?LayoutParams.TYPE_PHONE;??????????????????bigWindowParams.format?=?PixelFormat.RGBA_8888;??????????????????bigWindowParams.gravity?=?Gravity.LEFT?|?Gravity.TOP;??????????????????bigWindowParams.width?=?FloatWindowBigView.viewWidth;??????????????????bigWindowParams.height?=?FloatWindowBigView.viewHeight;??????????????}??????????????windowManager.addView(bigWindow,?bigWindowParams);??????????}??????}????????????????public?static?void?removeBigWindow(Context?context)?{??????????if?(bigWindow?!=?null)?{??????????????WindowManager?windowManager?=?getWindowManager(context);??????????????windowManager.removeView(bigWindow);??????????????bigWindow?=?null;??????????}??????}????????????????public?static?void?createLauncher(Context?context)?{??????????WindowManager?windowManager?=?getWindowManager(context);??????????int?screenWidth?=?windowManager.getDefaultDisplay().getWidth();??????????int?screenHeight?=?windowManager.getDefaultDisplay().getHeight();??????????if?(rocketLauncher?==?null)?{??????????????rocketLauncher?=?new?RocketLauncher(context);??????????????if?(launcherParams?==?null)?{??????????????????launcherParams?=?new?LayoutParams();??????????????????launcherParams.x?=?screenWidth?/?2?-?RocketLauncher.width?/?2;??????????????????launcherParams.y?=?screenHeight?-?RocketLauncher.height;??????????????????launcherParams.type?=?LayoutParams.TYPE_PHONE;??????????????????launcherParams.format?=?PixelFormat.RGBA_8888;??????????????????launcherParams.gravity?=?Gravity.LEFT?|?Gravity.TOP;??????????????????launcherParams.width?=?RocketLauncher.width;??????????????????launcherParams.height?=?RocketLauncher.height;??????????????}??????????????windowManager.addView(rocketLauncher,?launcherParams);??????????}??????}????????????????public?static?void?removeLauncher(Context?context)?{??????????if?(rocketLauncher?!=?null)?{??????????????WindowManager?windowManager?=?getWindowManager(context);??????????????windowManager.removeView(rocketLauncher);??????????????rocketLauncher?=?null;??????????}??????}????????????????public?static?void?updateLauncher()?{??????????if?(rocketLauncher?!=?null)?{??????????????rocketLauncher.updateLauncherStatus(isReadyToLaunch());??????????}??????}???????????????????public?static?void?updateUsedPercent(Context?context)?{??????????if?(smallWindow?!=?null)?{??????????????TextView?percentView?=?(TextView)?smallWindow??????????????????????.findViewById(R.id.percent);??????????????percentView.setText(getUsedPercentValue(context));??????????}??????}??????????????????public?static?boolean?isWindowShowing()?{??????????return?smallWindow?!=?null?||?bigWindow?!=?null;??????}??????????????????public?static?boolean?isReadyToLaunch()?{??????????if?((smallWindowParams.x?>?launcherParams.x?&&?smallWindowParams.x??????????????????+?smallWindowParams.width?<?launcherParams.x??????????????????+?launcherParams.width)??????????????????&&?(smallWindowParams.y?+?smallWindowParams.height?>?launcherParams.y))?{??????????????return?true;??????????}??????????return?false;??????}????????????????????private?static?WindowManager?getWindowManager(Context?context)?{??????????if?(mWindowManager?==?null)?{??????????????mWindowManager?=?(WindowManager)?context??????????????????????.getSystemService(Context.WINDOW_SERVICE);??????????}??????????return?mWindowManager;??????}????????????????????private?static?ActivityManager?getActivityManager(Context?context)?{??????????if?(mActivityManager?==?null)?{??????????????mActivityManager?=?(ActivityManager)?context??????????????????????.getSystemService(Context.ACTIVITY_SERVICE);??????????}??????????return?mActivityManager;??????}????????????????????public?static?String?getUsedPercentValue(Context?context)?{??????????String?dir?=?"/proc/meminfo";??????????try?{??????????????FileReader?fr?=?new?FileReader(dir);??????????????BufferedReader?br?=?new?BufferedReader(fr,?2048);??????????????String?memoryLine?=?br.readLine();??????????????String?subMemoryLine?=?memoryLine.substring(memoryLine??????????????????????.indexOf("MemTotal:"));??????????????br.close();??????????????long?totalMemorySize?=?Integer.parseInt(subMemoryLine.replaceAll(??????????????????????"\\D+",?""));??????????????long?availableSize?=?getAvailableMemory(context)?/?1024;??????????????int?percent?=?(int)?((totalMemorySize?-?availableSize)??????????????????????/?(float)?totalMemorySize?*?100);??????????????return?percent?+?"%";??????????}?catch?(IOException?e)?{??????????????e.printStackTrace();??????????}??????????return?"懸浮窗";??????}????????????????????private?static?long?getAvailableMemory(Context?context)?{??????????ActivityManager.MemoryInfo?mi?=?new?ActivityManager.MemoryInfo();??????????getActivityManager(context).getMemoryInfo(mi);??????????return?mi.availMem;??????}????}??
MyWindowManager是所有桌面懸浮窗的管理器,這里我們主要添加了createLauncher()、removeLauncher()和updateLauncher()這幾個方法,分別用于創建、移除、以及更新火箭發射臺懸浮窗。另外還添加了isReadyToLaunch()這個方法,它是用于判斷小火箭是否已經拖動到火箭發射臺上了。判斷的方式當然也很簡單,只需要對小火箭的邊界和火箭發射臺的邊界進行檢測,判斷它們是否相交就行了。
接下來還需要修改FloatWindowSmallView中的代碼,當手指拖動懸浮窗的時候要將它變成小火箭,如下所示:
[java] view plaincopy
public?class?FloatWindowSmallView?extends?LinearLayout?{????????????????public?static?int?windowViewWidth;????????????????public?static?int?windowViewHeight;????????????????private?static?int?statusBarHeight;????????????????private?WindowManager?windowManager;????????????????private?LinearLayout?smallWindowLayout;????????????????private?ImageView?rocketImg;????????????????private?WindowManager.LayoutParams?mParams;????????????????private?float?xInScreen;????????????????private?float?yInScreen;????????????????private?float?xDownInScreen;????????????????private?float?yDownInScreen;????????????????private?float?xInView;????????????????private?float?yInView;????????????????private?int?rocketWidth;????????????????private?int?rocketHeight;????????????????private?boolean?isPressed;????????public?FloatWindowSmallView(Context?context)?{??????????super(context);??????????windowManager?=?(WindowManager)?context??????????????????.getSystemService(Context.WINDOW_SERVICE);??????????LayoutInflater.from(context).inflate(R.layout.float_window_small,?this);??????????smallWindowLayout?=?(LinearLayout)?findViewById(R.id.small_window_layout);??????????windowViewWidth?=?smallWindowLayout.getLayoutParams().width;??????????windowViewHeight?=?smallWindowLayout.getLayoutParams().height;??????????rocketImg?=?(ImageView)?findViewById(R.id.rocket_img);??????????rocketWidth?=?rocketImg.getLayoutParams().width;??????????rocketHeight?=?rocketImg.getLayoutParams().height;??????????TextView?percentView?=?(TextView)?findViewById(R.id.percent);??????????percentView.setText(MyWindowManager.getUsedPercentValue(context));??????}????????@Override??????public?boolean?onTouchEvent(MotionEvent?event)?{??????????switch?(event.getAction())?{??????????case?MotionEvent.ACTION_DOWN:??????????????isPressed?=?true;????????????????????????????xInView?=?event.getX();??????????????yInView?=?event.getY();??????????????xDownInScreen?=?event.getRawX();??????????????yDownInScreen?=?event.getRawY()?-?getStatusBarHeight();??????????????xInScreen?=?event.getRawX();??????????????yInScreen?=?event.getRawY()?-?getStatusBarHeight();??????????????break;??????????case?MotionEvent.ACTION_MOVE:??????????????xInScreen?=?event.getRawX();??????????????yInScreen?=?event.getRawY()?-?getStatusBarHeight();????????????????????????????updateViewStatus();??????????????updateViewPosition();??????????????break;??????????case?MotionEvent.ACTION_UP:??????????????isPressed?=?false;??????????????if?(MyWindowManager.isReadyToLaunch())?{??????????????????launchRocket();??????????????}?else?{??????????????????updateViewStatus();????????????????????????????????????if?(xDownInScreen?==?xInScreen?&&?yDownInScreen?==?yInScreen)?{??????????????????????openBigWindow();??????????????????}??????????????}??????????????break;??????????default:??????????????break;??????????}??????????return?true;??????}???????????????????public?void?setParams(WindowManager.LayoutParams?params)?{??????????mParams?=?params;??????}????????????????private?void?launchRocket()?{??????????MyWindowManager.removeLauncher(getContext());??????????new?LaunchTask().execute();??????}????????????????private?void?updateViewPosition()?{??????????mParams.x?=?(int)?(xInScreen?-?xInView);??????????mParams.y?=?(int)?(yInScreen?-?yInView);??????????windowManager.updateViewLayout(this,?mParams);??????????MyWindowManager.updateLauncher();??????}????????????????private?void?updateViewStatus()?{??????????if?(isPressed?&&?rocketImg.getVisibility()?!=?View.VISIBLE)?{??????????????mParams.width?=?rocketWidth;??????????????mParams.height?=?rocketHeight;??????????????windowManager.updateViewLayout(this,?mParams);??????????????smallWindowLayout.setVisibility(View.GONE);??????????????rocketImg.setVisibility(View.VISIBLE);??????????????MyWindowManager.createLauncher(getContext());??????????}?else?if?(!isPressed)?{??????????????mParams.width?=?windowViewWidth;??????????????mParams.height?=?windowViewHeight;??????????????windowManager.updateViewLayout(this,?mParams);??????????????smallWindowLayout.setVisibility(View.VISIBLE);??????????????rocketImg.setVisibility(View.GONE);??????????????MyWindowManager.removeLauncher(getContext());??????????}??????}????????????????private?void?openBigWindow()?{??????????MyWindowManager.createBigWindow(getContext());??????????MyWindowManager.removeSmallWindow(getContext());??????}??????????????????private?int?getStatusBarHeight()?{??????????if?(statusBarHeight?==?0)?{??????????????try?{??????????????????Class<?>?c?=?Class.forName("com.android.internal.R$dimen");??????????????????Object?o?=?c.newInstance();??????????????????Field?field?=?c.getField("status_bar_height");??????????????????int?x?=?(Integer)?field.get(o);??????????????????statusBarHeight?=?getResources().getDimensionPixelSize(x);??????????????}?catch?(Exception?e)?{??????????????????e.printStackTrace();??????????????}??????????}??????????return?statusBarHeight;??????}??????????????????class?LaunchTask?extends?AsyncTask<Void,?Void,?Void>?{????????????@Override??????????protected?Void?doInBackground(Void...?params)?{????????????????????????????while?(mParams.y?>?0)?{??????????????????mParams.y?=?mParams.y?-?10;??????????????????publishProgress();??????????????????try?{??????????????????????Thread.sleep(8);??????????????????}?catch?(InterruptedException?e)?{??????????????????????e.printStackTrace();??????????????????}??????????????}??????????????return?null;??????????}????????????@Override??????????protected?void?onProgressUpdate(Void...?values)?{??????????????windowManager.updateViewLayout(FloatWindowSmallView.this,?mParams);??????????}????????????@Override??????????protected?void?onPostExecute(Void?result)?{????????????????????????????updateViewStatus();??????????????mParams.x?=?(int)?(xDownInScreen?-?xInView);??????????????mParams.y?=?(int)?(yDownInScreen?-?yInView);??????????????windowManager.updateViewLayout(FloatWindowSmallView.this,?mParams);??????????}????????}????}??
這里在代碼中添加了一個isPressed標識位,用于判斷用戶是否正在拖動懸浮窗。當拖動的時候就調用updateViewStatus()方法來更新懸浮窗的顯示狀態,這時懸浮窗就會變成一個小火箭。然后當手指離開屏幕的時候,也會調用updateViewStatus()方法,這時發現isPressed為false,就會將懸浮窗重新顯示出來。
同時,當手指離開屏幕的時候,還會調用MyWindowManager的isReadyToLaunch()方法來判斷小火箭是否被拖動到火箭發射臺上了,如果為true,就會觸發火箭升空的動畫效果。火箭升空的動畫實現是寫在LaunchTask這個任務里的,可以看到,這里會在doInBackground()方法中執行耗時邏輯,將小火箭的縱坐標不斷減小,以讓它實現上升的效果。當縱坐標減小到0的時候,火箭升空的動畫就結束了,然后在onPostExecute()方法中重新將懸浮窗顯示出來。
另外,在AndroidManifest.xml文件中記得要聲明兩個權限,如下所示:
[html]?view plaincopy
<uses-permission?android:name="android.permission.SYSTEM_ALERT_WINDOW"?/>?? <uses-permission?android:name="android.permission.GET_TASKS"?/>??
代碼就只有這么多,接下來我們運行一下看看效果吧。在主界面點擊Start Float Window按鈕可以開啟懸浮窗并回到桌面,然后拖動懸浮窗后就會變成小火箭的狀態,將它拖動到屏幕底部火箭發射臺上,然后放手,小火箭就會騰空而起了,如下圖所示:
下載:http://download.csdn.net/detail/sinyu890807/6786059
總結
以上是生活随笔為你收集整理的Android桌面悬浮窗进阶,QQ手机管家小火箭效果实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。