Android desktop floating window advanced, QQ mobile phone Butler little rocket effect implementation

Source: Internet
Author: User

 

Today is the last day of March 2013. We wish you a happy New Year! At the same time, this article is my last article this year. Therefore, I want to make it as special as possible. It has more characteristics than the usual articles. I remember that at the beginning of this year, the first article I wrote was to imitate the desktop floating window effect of 360 mobile guard, so in order to be able to echo at the beginning and end, the last article of this year is also about implementing the desktop floating window effect. Of course, the effect will be more advanced.

I believe that anyone who has used QQ Mobile Phone Manager will know that it has a small rocket acceleration function. If you drag a small rocket onto the rocket launch platform, an animation of the rocket's launch will appear, so today we will simulate this effect.

This time, we will focus on the effectiveness of the Code when the rocket is launched. For simplicity, we will continue to develop the code based on the code that imitates the floating window of 360 mobile guard, if you have not read this article, we recommend that you first read the floating window effect of the Android desktop, to simulate the floating window effect of 360 mobile guard.

Compared with the ordinary desktop floating window, we need to change the floating window into a small rocket while dragging the floating window, and add a rocket launcher at the bottom of the screen. Let's start with writing the rocket launcher. First, create launcher. xml as the layout file of the rocket launcher, as shown below:

 
         
      
  
 
As you can see, the ImageView is used to display the status of the current rocket launcher. I have prepared two pictures in advance. One is shown when the little rocket is not dragged to the rocket launch platform, and the other is displayed when the little rocket is dragged to the rocket launch platform.

 

Next, create the RocketLauncher class as the View of the rocket launcher. The Code is as follows:

Public class RocketLauncher extends LinearLayout {/*** record the width of the rocket launcher */public static int width;/*** record the height of the rocket launcher */public static int height; /*** background image of the rocket launcher */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 (). wi Dth; height = launcherImg. getLayoutParams (). height ;}/ *** update the display status of the rocket launcher. If a small rocket is dragged to the rocket launch stage, the launch will be displayed. */Public void updateLauncherStatus (boolean isReadyToLaunch) {if (isReadyToLaunch) {launcherImg. setImageResource (R. drawable. launcher_bg_fire);} else {launcherImg. setImageResource (R. drawable. launcher_bg_hold );}}}
The code in RocketLauncher is very simple. In the build method, the LayoutInflater's inflate () method is called to set launcher. the xml layout file is loaded and the width and height of the current View are obtained. The updateLauncherStatus () method determines whether the input parameter is true. If the input parameter is true, the image to be launched by the minor rocket is displayed. If the input parameter is false, the image of dragging the rocket to the launch platform is displayed.

 

There are only two new files, and the rest is to modify the previous code. Modify the code in MyWindowManager as follows:

Public class MyWindowManager {/*** small floating window View instance */private static FloatWindowSmallView smallWindow;/*** large floating window View instance */private static FloatWindowBigView bigWindow; /*** rocket launch instance */private static RocketLauncher rocketLauncher;/*** parameters of the small floating window View */private static LayoutParams smallWindowParams; /* large floating window View parameters */private static LayoutParams bigWindowParams;/* rocket launch station parameters */private static LayoutParams la UncherParams;/*** used to control the addition or removal of floating windows on the screen */private static WindowManager mWindowManager;/*** used to obtain available memory on the mobile phone */private static ActivityManager mActivityManager; /*** create a small floating window. The initial position is the center right of the screen. */Public static void createSmallWindow (Context context) {WindowManager windowManager = getWindowManager (context); int screenWidth = windowManager. getdefadisplay display (). getWidth (); int screenHeight = windowManager. getdefadisplay display (). getHeight (); if (smallWindow = null) {smallWindow = new FloatWindowSmallView (context); if (smallWindowParams = null) {smallWindowParams = new LayoutParams (); smallWindowPar Ams. 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) ;}}/*** remove a small floating window from the screen. */Public static void removeSmallWindow (Context context) {if (smallWindow! = Null) {WindowManager windowManager = getWindowManager (context); windowManager. removeView (smallWindow); smallWindow = null ;}/ *** create a large floating window. In the center of the screen. */Public static void createBigWindow (Context context) {WindowManager windowManager = getWindowManager (context); int screenWidth = windowManager. getdefadisplay display (). getWidth (); int screenHeight = windowManager. getdefadisplay display (). getHeight (); if (bigWindow = null) {bigWindow = new FloatWindowBigView (context); if (bigWindowParams = null) {bigWindowParams = new LayoutParams (); bigWindowParams. x = screen Width/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 (bigWin Dow, bigWindowParams) ;}}/*** remove the large floating window from the screen. */Public static void removeBigWindow (Context context) {if (bigWindow! = Null) {WindowManager windowManager = getWindowManager (context); windowManager. removeView (bigWindow); bigWindow = null ;}/ *** creates a rocket launcher at the bottom of the screen. */Public static void createLauncher (Context context) {WindowManager windowManager = getWindowManager (context); int screenWidth = windowManager. getdefadisplay display (). getWidth (); int screenHeight = windowManager. getdefadisplay display (). getHeight (); if (rocketLauncher = null) {rocketLauncher = new RocketLauncher (context); if (launcherParams = null) {launcherParams = new LayoutParams (); launcherParams. x = scre EnWidth/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);}/*** extract the rocket launcher from the screen Removed from the screen. */Public static void removeLauncher (Context context) {if (rocketLauncher! = Null) {WindowManager windowManager = getWindowManager (context); windowManager. removeView (rocketLauncher); rocketLauncher = null ;}}/*** updates the display status of the rocket launcher. */Public static void updateLauncher () {if (rocketLauncher! = Null) {rocketLauncher. updateLauncherStatus (isReadyToLaunch ();}/*** update the data on the TextView of the small floating window and display the percentage of memory usage. ** @ Param context * indicates the application context. */Public static void updateUsedPercent (Context context) {if (smallWindow! = Null) {TextView percentView = (TextView) smallWindow. findViewById (R. id. percent); percentView. setText (getUsedPercentValue (context) ;}/ *** whether a floating window (including a small floating window and a large floating window) is displayed on the screen. ** @ Return returns true if a floating window is displayed on the desktop. If not, returns false. */Public static boolean isWindowShowing () {return smallWindow! = Null | bigWindow! = Null;}/*** determines whether the rocket is ready for launch. ** @ Return: If a rocket is sent to the launch platform, true is returned. Otherwise, false is returned. */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;}/*** if WindowManager is not created yet, a new WindowManager is created and returned. Otherwise, the created WindowManager is returned. ** @ Param context * must be the application's Context. * @ return WindowManager instance, used to control the addition or removal of floating windows on the screen. */Private static WindowManager getWindowManager (Context context) {if (mWindowManager = null) {mWindowManager = (WindowManager) context. getSystemService (Context. WINDOW_SERVICE);} return mWindowManager;}/*** if ActivityManager is not created yet, a new ActivityManager is created and returned. Otherwise, the created ActivityManager is returned. ** @ Param context * indicates the application context. * @ Return ActivityManager instance, used to obtain the available memory of the mobile phone. */Private static ActivityManager getActivityManager (Context context) {if (mActivityManager = null) {mActivityManager = (ActivityManager) context. getSystemService (Context. ACTIVITY_SERVICE);} return mActivityManager;}/*** calculates the percentage of memory in use and returns. ** @ Param context * indicates the application context. * @ Return the percentage of memory used, which is returned as a string. */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 = getAvail AbleMemory (context)/1024; int percent = (int) (totalMemorySize-availableSize)/(float) totalMemorySize * 100); return percent + %;} catch (IOException e) {e. printStackTrace ();} return floating window;}/*** obtains the current available memory, and the returned data is in bytes. ** @ Param context * indicates the application context. * @ Return the current available memory. */Private static long getAvailableMemory (Context context) {ActivityManager. MemoryInfo mi = new ActivityManager. MemoryInfo (); getActivityManager (context). getMemoryInfo (mi); return mi. availMem ;}}
MyWindowManager is the manager for all desktop floating windows. Here we mainly add the createLauncher (), removeLauncher (), and updateLauncher () methods, they are used to create, remove, and update rocket launcher floating windows respectively. In addition, the isReadyToLaunch () method is added to determine whether the small rocket has been dragged to the rocket launch platform. The method of judgment is also very simple. You only need to check the boundaries of the small rocket and the rocket launch station and determine whether they are at the intersection.

 

Next, you need to modify the code in FloatWindowSmallView. When you drag the floating window with your fingers, you need to change it to a small rocket, as shown below:

Public class FloatWindowSmallView extends LinearLayout {/*** record the width of a small floating window */public static int windowViewWidth;/*** record the height of a small floating window */public static int windowViewHeight; /*** record the height of the system status bar */private static int statusBarHeight;/*** used to update the location of the small floating window */private WindowManager windowManager; /*** layout of the small floating window */private LinearLayout smallWindowLayout;/*** Rocket control */private ImageView rocketImg; /*** parameters of the small floating window */private WindowMan Ager. layoutParams mParams;/*** record the abscissa value of the current finger position on the screen */private float xInScreen; /*** record the ordinate value of the current finger position on the screen */private float yInScreen; /*** record the abscissa value on the screen when the finger is pressed */private float xDownInScreen; /*** record the ordinate value on the screen when the finger is pressed */private float yDownInScreen; /*** record the horizontal coordinate value of the View in the small floating window when the finger is pressed */private float xInView; /*** record the ordinate value of the View on the small floating window when the finger is pressed */private float yInView;/*** record the width of the small rocket */private int rocketWidth; /*** record the height of a small rocket */Private int rocketHeight;/*** record whether the current finger is pressed */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. getL AyoutParams (). 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);} @ Overridepublic boolean onTouchEvent (M OtionEvent) {switch (event. getAction () {case MotionEvent. ACTION_DOWN: isPressed = true; // the required data is recorded when the finger is pressed. The values of the ordinate values must be subtracted from the height of the status bar 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 (); yI NScreen = event. getRawY ()-getStatusBarHeight (); // update the status and position of the small floating window when the finger moves. updateViewStatus (); updateViewPosition (); break; case MotionEvent. ACTION_UP: isPressed = false; if (MyWindowManager. isReadyToLaunch () {launchRocket ();} else {updateViewStatus (); // If the finger leaves the screen, xDownInScreen and xInScreen are equal, and yDownInScreen and yInScreen are equal, the click event is triggered. If (xDownInScreen = xInScreen & yDownInScreen = yInScreen) {openBigWindow () ;}} break; default: break;} return true ;} /*** pass in the parameters of the small floating window to update the position of the small floating window. ** @ Param params * parameter of the small floating window */public void setParams (WindowManager. LayoutParams params) {mParams = params;}/*** used to launch a small rocket. */Private void launchRocket () {MyWindowManager. removeLauncher (getContext (); new launchtask(cmd.exe cute ();}/*** updates the position of the small floating window on the screen. */Private void updateViewPosition () {mParams. x = (int) (xInScreen-xInView); mParams. y = (int) (yInScreen-yInView); windowManager. updateViewLayout (this, mParams); MyWindowManager. updateLauncher ();}/*** updates the View display status to determine whether the View is a floating window or a small rocket. */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 () ;}}/*** open the large floating window and close the small floating window. */Private void openBigWindow () {MyWindowManager. createBigWindow (getContext (); MyWindowManager. removeSmallWindow (getContext ();}/*** gets the height of the status bar. ** @ Return returns the pixel value of the status bar height. */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;}/*** starts the task of launching a small rocket. ** @ Author guolin */class LaunchTask extends AsyncTask
 
  
{@ Overrideprotected Void doInBackground (Void... params) {// here the position of the minor rocket is changed to produce the rocket lift effect while (mParams. y> 0) {mParams. y = mParams. y-10; publishProgress (); try {Thread. sleep (8);} catch (InterruptedException e) {e. printStackTrace () ;}} return null ;}@ Overrideprotected void onProgressUpdate (Void... values) {windowManager. updateViewLayout (FloatWindowSmallView. this, mParams) ;}@ Overrideprotected void onPostExecute (Void result) {// After the rocket is lifted, it returns to the floating window status updateViewStatus (); mParams. x = (int) (xDownInScreen-xInView); mParams. y = (int) (yDownInScreen-yInView); windowManager. updateViewLayout (FloatWindowSmallView. this, mParams );}}}
 
Here, an isPressed flag is added to the Code to determine whether the user is dragging the floating window. When dragging, call the updateViewStatus () method to update the display status of the floating window. Then the floating window will become a small rocket. When the finger leaves the screen, the updateViewStatus () method is also called. If isPressed is false, the floating window is displayed again.

 

At the same time, when the finger leaves the screen, the MyWindowManager isReadyToLaunch () method will be called to determine whether the rocket is dragged to the rocket launch platform. If it is true, it will trigger the animation effect of the rocket. The animation of the rocket is written in the LaunchTask task. We can see that the time-consuming logic is executed in the doInBackground () method to reduce the ordinate of the minor rocket, to improve the performance. When the ordinate value is reduced to 0, the animation for the rocket to take off is over, and the floating window is displayed again in the onPostExecute () method.

In addition, remember to declare two permissions in the AndroidManifest. xml file, as shown below:

 
  
 
There is only so much code. Let's run it to see the effect. On the main interface, click the Start Float Window button to open the floating Window and return to the desktop. Then, drag the floating Window and it will become the state of the rocket. Drag it to the rocket launch stage at the bottom of the screen, then let the rocket go, as shown in:

Well, today's explanation is here. With the departure of the minor rocket, my last article this year is over.

The New Year is coming soon. I hope you can take off in the next year, like this little rocket, to reach a new height! In 2014, we continue to work together!

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.