Now a lot of security software, such as 360 mobile phone assistant, Baidu mobile phone assistant, etc., have a floating window, you can float on the desktop, user-friendly use of some commonly used operations.
Today, this article is about how to achieve the desktop suspension window effect.
First, look at the effect chart.
The suspension window is divided into two parts, one is the usual display of small window, the other is to click on a small window to display the two-level suspension window.
First, look at the directory structure of the project.
The key is the red box in the four classes.
First of all, Floatwindowservice is a background service class, mainly responsible for in the background constantly refresh the small suspension window on the desktop, otherwise it will lead to the replacement of the interface, the suspension window will disappear, so need to constantly refresh. Here is the implementation code.
Package Com.qust.floatwindow;
Import Java.util.Timer;
Import Java.util.TimerTask;
Import Android.app.Service;
Import Android.content.Context;
Import android.content.Intent;
Import Android.os.Handler;
Import Android.os.IBinder; /** * Suspension Window Background Service * * @author Zhaokaiqiang * */public class Floatwindowservice extends service {public static final S
Tring layout_res_id = "Layoutresid";
public static final String root_layout_id = "Rootlayoutid";
Used to create/remove/update suspension windows in threads private Handler Handler = new Handler ();
private context;
private timer timer;
Small window layout resource ID private int layoutresid;
Layout root layout id private int rootlayoutid;
@Override public int Onstartcommand (Intent Intent, int flags, int startid) {context = this;
Layoutresid = Intent.getintextra (layout_res_id, 0);
Rootlayoutid = Intent.getintextra (root_layout_id, 0); if (Layoutresid = = 0 | | rootlayoutid = 0) {throw new IllegalArgumentException ("Layoutresid or Rootlayoutid is illegal
"); } if (timer = = null) {timer = new timer ();
Perform a refresh task once every 500 milliseconds timer.scheduleatfixedrate (new Refreshtask (), 0, 500);
Return Super.onstartcommand (Intent, flags, Startid);
@Override public void OnDestroy () {Super.ondestroy ();
Service is terminated at the same time also stop timer continue to run Timer.cancel ();
timer = null; Private class Refreshtask extends TimerTask {@Override public void run () {//The current interface does not have a floating window display, then create a suspension if (!). Floatwindowmanager.getinstance. Iswindowshowing ()) {Handler.post (new Runnable () {@Override public void run ()
{floatwindowmanager.getinstance (context)-Createsmallwindow (context, Layoutresid, Rootlayoutid);
}
});
@Override public IBinder onbind (Intent Intent) {return null; }
}
In addition to the background service, we also need two custom layouts, respectively, Floatwindowsmallview and Floatwindowbigview, these two custom layouts, mainly responsible for the suspension window foreground display, we look at the code implementation.
The first is the implementation of the Floatwindowsmallview class.
Package Com.qust.floatwindow;
Import Java.lang.reflect.Field;
Import Android.annotation.SuppressLint;
Import Android.content.Context;
Import Android.graphics.PixelFormat;
Import android.view.Gravity;
Import Android.view.LayoutInflater;
Import android.view.MotionEvent;
Import Android.view.View;
Import Android.view.WindowManager;
Import Android.widget.LinearLayout;
Import Android.widget.TextView;
Import Com.qust.demo.ScreenUtils;
Import COM.QUST.FLOATINGWINDOW.R;
/** * Small suspension window for initial display * * * @author Zhaokaiqiang * */public class Floatwindowsmallview extends LinearLayout {//Small suspension window width
public int viewwidth;
High public int viewheight with small suspension window;
The System status bar is highly private static int statusbarheight;
Used to update the position of the small suspension window private WindowManager WindowManager;
The layout parameters of the small suspension window public windowmanager.layoutparams smallwindowparams;
Record the current finger position on the screen on the horizontal axis private float xinscreen;
Record the current finger position on the screen ordinate private float yinscreen;
Record the horizontal axis on the screen when the finger is pressed to determine the click event Private float Xdowninscreen; Record the finger when pressed on the screenOn the ordinate, used to determine the click event Private float Ydowninscreen;
Record the horizontal axis of the view on the small suspension window when the finger is pressed private float xinview;
Record the ordinate private float yinview on the view of the small suspension window when the finger is pressed;
Click the interface private Onclicklistener listener; /** * Constructor * @param context Object * @param layoutresid * Layout Resource ID * @param rootlayoutid * Root Layout ID * * Public Floa
Twindowsmallview (context, int layoutresid, int rootlayoutid) {super (context);
WindowManager = (windowmanager) context. Getsystemservice (Context.window_service);
Layoutinflater.from (context)-Inflate (layoutresid, this);
View view = Findviewbyid (Rootlayoutid);
Viewwidth = View.getlayoutparams (). width;
Viewheight = View.getlayoutparams (). Height;
Statusbarheight = Getstatusbarheight ();
TextView Percentview = (TextView) Findviewbyid (r.id.percent);
Percentview.settext ("suspension window");
Smallwindowparams = new Windowmanager.layoutparams ();
Set the display type to PHONE smallwindowparams.type = WindowManager.LayoutParams.TYPE_PHONE; Show Picture Format Smallwindowparams.format = Pixelformat.rgba_8888; Set Interactive mode smallwindowparams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; Set alignment to upper left smallwindowparams.gravity = Gravity.left |
Gravity.top;
Smallwindowparams.width = Viewwidth;
Smallwindowparams.height = Viewheight;
Smallwindowparams.x = screenutils.getscreenwidth (context);
Smallwindowparams.y = screenutils.getscreenheight (context)/2; @SuppressLint ("clickableviewaccessibility") @Override public boolean ontouchevent (Motionevent event) {switch (event
. Getaction ()) {//When the finger presses the necessary data, the ordinate value minus the status bar height case Motionevent.action_down://Get the relative and small suspension window coordinates xinview = Event.getx ();
Yinview = Event.gety ();
The position of the coordinates when pressed, recording only once xdowninscreen = Event.getrawx ();
Ydowninscreen = Event.getrawy ()-statusbarheight;
Break
Case Motionevent.action_move://constantly update the position of the current finger on the screen xinscreen = Event.getrawx ();
Yinscreen = Event.getrawy ()-statusbarheight;
Update the position of the small suspension window when the finger moves updateviewposition ();
Break Case MOTIONEVENT.ACTION_UP://If the finger is left on the screen and the coordinates are equal to the current coordinates, it is considered to trigger the Click event (Xdowninscreen = = EVENT.GETRAWX () && Ydowninscreen = = (event.g
Etrawy ()-getstatusbarheight ())) {if (listener!= null) {Listener.click ();
}} break;
return true;
/** * Sets the callback interface for the Click event/public void Setonclicklistener (Onclicklistener listener) {This.listener = listener;
/** * Update the position of the small suspension window in the screen * * private void Updateviewposition () {smallwindowparams.x = (int) (Xinscreen-xinview);
SMALLWINDOWPARAMS.Y = (int) (Yinscreen-yinview);
Windowmanager.updateviewlayout (this, smallwindowparams); /** * Gets the height of the status bar * * @return/private int getstatusbarheight () {try {class<?> c = class.forname ("Com.and
Roid.internal.r$dimen ");
Object o = c.newinstance ();
Field field = C.getfield ("Status_bar_height");
int x = (Integer) field.get (o);
Return Getresources (). getdimensionpixelsize (x);
catch (Exception e) {e.printstacktrace ();
return 0; /** * Click interface * * @author Zhaokaiqiang */Public Interface Onclicklistener {public void click (); }
}
In this class, the main task is to implement the suspension window on the desktop front-end implementation, as well as the location of the movement and click events to judge and deal with. Here are some of the methods and attributes that are mainly WindowManager classes, which are described in detail in the next article, which is only said to be implemented.
In addition to the small suspension window, after the click of the pop-up two-level suspension window is also a similar way to add to the desktop, below is the two-level suspension window code.
Package Com.qust.floatwindow;
Import Android.content.Context;
Import Android.graphics.PixelFormat;
Import android.view.Gravity;
Import Android.view.LayoutInflater;
Import Android.view.View;
Import Android.view.WindowManager;
Import Android.widget.LinearLayout;
Import Android.widget.TextView;
Import Com.qust.demo.ScreenUtils;
Import COM.QUST.FLOATINGWINDOW.R;
public class Floatwindowbigview extends LinearLayout {//record wide public int viewwidth for large suspension windows;
High public int viewheight for recording large suspension windows;
Public Windowmanager.layoutparams Bigwindowparams;
private context;
Public Floatwindowbigview {Super (context);
This.context = context;
Layoutinflater.from (context)-Inflate (r.layout.float_window_big, this);
View view = Findviewbyid (r.id.big_window_layout);
Viewwidth = View.getlayoutparams (). width;
Viewheight = View.getlayoutparams (). Height;
Bigwindowparams = new Windowmanager.layoutparams (); Sets the location of the display, the default is the screen center bigwindowparams.x = Screenutils.getscreenwidth (context)/2-VIEWWIDTH/2;
Bigwindowparams.y = screenutils.getscreenheight (context)/2-VIEWHEIGHT/2;
Bigwindowparams.type = WindowManager.LayoutParams.TYPE_PHONE;
Bigwindowparams.format = pixelformat.rgba_8888; Set Interactive mode bigwindowparams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; bigwindowparams.gravity = Gravity.left |
Gravity.top;
Bigwindowparams.width = Viewwidth;
Bigwindowparams.height = Viewheight;
Initview ();
private void Initview () {TextView tv_back = (TextView) Findviewbyid (r.id.tv_back); Tv_back.setonclicklistener (New Onclicklistener () {@Override public void OnClick (View v) {Floatwindowmanager.getinstan
CE (context). Removebigwindow ();
}
}); }
}
When
These basic classes are established, the rest is the implementation of the most important class Floatwindowmanager. This class implements the operation of the suspension window.
Package Com.qust.floatwindow;
Import Android.content.Context;
Import android.content.Intent;
Import Android.view.WindowManager; /** * Suspension Window Manager * * * @author Zhaokaiqiang * */public class Floatwindowmanager {//Small suspension window object Private Floatwindowsmallvie
W Smallwindow;
Large suspension Window objects private Floatwindowbigview Bigwindow;
Used to control adding or removing a floating window on the screen private WindowManager Mwindowmanager;
Floatwindowmanager single case private static Floatwindowmanager Floatwindowmanager;
The context object is private;
Private Floatwindowmanager {this.context = context; public static Floatwindowmanager getinstance {if (Floatwindowmanager = = null) {Floatwindowmanager
= new Floatwindowmanager (context);
return floatwindowmanager;
/** * Create a small suspension window * * @param context * must be the context of the application. */public void Createsmallwindow (context context, int layoutresid, int rootlayoutid) {WindowManager WindowManager = ge
Twindowmanager (); if (Smallwindow = = null) {Smallwindow = New Floatwindowsmallview (context, Layoutresid, Rootlayoutid);
Windowmanager.addview (Smallwindow, smallwindow.smallwindowparams); }/** * Removes the small suspension window from the screen * * @param context/public void Removesmallwindow () {if (Smallwindow!= null) {windowma
Nager WindowManager = Getwindowmanager ();
Windowmanager.removeview (Smallwindow);
Smallwindow = null; }} public void Setonclicklistener (Floatwindowsmallview.onclicklistener listener) {if (Smallwindow!= null) {SMALLWI
Ndow.setonclicklistener (listener);
}/** * Create a large suspension window * * @param context * must be the context of the application.
* * public void Createbigwindow (context context) {WindowManager WindowManager = Getwindowmanager ();
if (Bigwindow = = null) {Bigwindow = new Floatwindowbigview (context);
Windowmanager.addview (Bigwindow, bigwindow.bigwindowparams); }/** * Remove the large suspension window from the screen * @param context/public void Removebigwindow () {if (Bigwindow!= null) {Windowmanage
R WindowManager = Getwindowmanager (); Windowmanager.removevieW (Bigwindow);
Bigwindow = null;
} public void RemoveAll () {Context.stopservice (new Intent (context, floatwindowservice.class));
Removesmallwindow ();
Removebigwindow (); /** * Whether there is a suspension window display (including small suspension window and large suspension) * * @return has a suspension window display on the desktop returns True, no words return false/public Boolean iswindowshowing () {returns Smallwindow!= Null | |
Bigwindow!= null; /** * If WindowManager has not been created, create a new WindowManager return. Otherwise, the current created WindowManager * * @param context * @return/private WindowManager Getwindowmanager () {if (mwindowmanage
r = = null) {Mwindowmanager = (WindowManager) context. Getsystemservice (Context.window_service);
return mwindowmanager; }
}
There's also a help class to get the screen wide.
Package Com.qust.demo;
Import Android.content.Context;
Import Android.view.WindowManager;
/**
* Screen Help class
*
* @author Zhaokaiqiang * */Public
class Screenutils {
/**
* Get screen width
*
* @return
/@SuppressWarnings ("deprecation") public
static int getscreenwidth Context) {return
(WindowManager) context
. Getsystemservice (Context.window_service)). Getdefaultdisplay ()
. getwidth ();
}
/**
* Get screen width
*
* @return
/@SuppressWarnings ("deprecation") public
static int Getscreenheight {return (
WindowManager) context
. Getsystemservice (Context.window_ SERVICE)). Getdefaultdisplay ()
. GetHeight ();
}
With this done, we can use it directly.
Package Com.qust.demo;
Import android.app.Activity;
Import Android.content.Context;
Import android.content.Intent;
Import Android.os.Bundle;
Import android.view.KeyEvent;
Import Android.view.View;
Import COM.QUST.FLOATINGWINDOW.R;
Import Com.qust.floatwindow.FloatWindowManager;
Import Com.qust.floatwindow.FloatWindowService;
Import Com.qust.floatwindow.FloatWindowSmallView.OnClickListener; /** * Sample * * @ClassName: Com.qust.demo.MainActivity * @Description: * @author Zhaokaiqiang * @date 2014-10-23 afternoon 11:3
0:13 * * * * * * */public class Mainactivity extends activity {private Floatwindowmanager Floatwindowmanager;
private context;
@Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_main);
context = this;
Floatwindowmanager = floatwindowmanager.getinstance (context); /** * Display Small window * * @param view/public void Show (view view) {//need to pass the small suspension window layout, as well as the root layout id, start the background service Intent Intent =New Intent (context, floatwindowservice.class);
Intent.putextra (floatwindowservice.layout_res_id, R.layout.float_window_small);
Intent.putextra (floatwindowservice.root_layout_id, r.id.small_window_layout);
StartService (Intent); /** * Display level two suspension window * * @param view/public void Showbig (view view) {//Set the Click event for a small suspension window Floatwindowmanager.setonclickli
Stener (New Onclicklistener () {@Override public void click () {Floatwindowmanager.createbigwindow (context);
}
});
/** * Remove all suspension windows * * @param view */public void Remove (view view) {Floatwindowmanager.removeall ();
@Override public boolean onKeyDown (int keycode, keyevent event) {//Return key to remove level two suspension window if (keycode = = Keyevent.keycode_back
&& event.getaction () = = Keyevent.action_down) {Floatwindowmanager.removebigwindow ();
return true;
Return Super.onkeydown (KeyCode, event); }
}
Project Download Address: Https://github.com/ZhaoKaiQiang/FloatWindow
In the above article, we introduced how to implement the desktop suspension window, in the implementation of this effect, one of the most important class is WindowManager, today's article, will introduce the use of WindowManager, and implementation of a use of WindowManager to enable users to open the app, showing the first use of teaching mask effect.
The WindowManager class implements the Viewmanager interface, and the Viewmanager interface allows us to add or remove view on the activity. So WindowManager also allows us to add and remove view on the activity.
We can get a WindowManager object in the following way
Copy Code code as follows:
Context.getsystemservice (Context.window_service)
In activity, we can get to a WindowManager object directly through Getwindowmanager ().
Each WindowManager instance is bound to a unique display object, and if we want to get a WindowManager object of different display, we can go through Createdisplaycontext (display) Get to this display's context object, and then use the above method, or you can get a WindowManager object.
When we use the WindowManager class, we usually use the following methods:
Windowmanager.addview (View,windowmanager.layoutparam);
Windowmanager.removeview ();
Windowmanager.getdefaultdisplay ();
The Windowmanager.addview () method is used to add a view object to the current window, and you need to accept two parameters, view is the View object to add to the window. And Windowmanager.layoutparam is added to the window parameters, in the previous add to the operation of the suspension window, the need for Layoutparam set a lot of parameters, the following we look at the commonly used settings
Set layoutparams parameter
layoutparams params = new Windowmanager.layoutparams ();
Set the type of display, type_phone refers to the phone will be overwritten, other times will be on the front end, the display position under Statebar, other more values please consult the documentation
Params.type = WindowManager.LayoutParams.TYPE_PHONE;
Set display format
Params.format = pixelformat.rgba_8888;
Set alignment
params.gravity = Gravity.left | Gravity.top;
Set width high
params.width = Screenutils.getscreenwidth (this);
Params.height = Screenutils.getscreenheight (this);
Sets the location of the display
params.x;
After setting the Layoutparam, we can add View to the window via Windowmanager.addview (View,windowmanager.layoutparam), but we need to declare the permissions
<uses-permissionandroid:name= "Android.permission.SYSTEM_ALERT_WINDOW"/>
After the addition is complete, we can see the view object we added on the window. If we want to remove the added view, we just need to call Windowmanager.removeview () and the argument is the View object we used earlier, and it's easy to use. In addition to this method, there is a windowmanager.removeviewimmediate (), you can also remove the view, but the document said that this method is not for the general program calls, and therefore need to be careful to use, we developed are the general procedures, It is not recommended to use this method.
In addition to these two methods, our most common method is Windowmanager.getdefaultdisplay (), in this way, we can get to the current interface of the display of an object, and then we can get to the current screen of some parameters, For example, wide height.
Here is a tool class that I often use.
Package com.qust.teachmask;
Import Android.content.Context;
Import Android.view.WindowManager;
/**
* Screen Help class
*
* @author Zhaokaiqiang * */Public
class Screenutils {
/**
* Get screen width
*
* @return
/@SuppressWarnings ("deprecation") public
static int getscreenwidth Context) {return
(WindowManager) context
. Getsystemservice (Context.window_service)). Getdefaultdisplay ()
. getwidth ();
}
/**
* Get screen width
*
* @return
/@SuppressWarnings ("deprecation") public
static int Getscreenheight {return (
WindowManager) context
. Getsystemservice (Context.window_ SERVICE)). Getdefaultdisplay ()
. GetHeight ();
}
Know above these, we can realize the teaching template effect, first look at the effect chart.
Here is the code implementation
Package com.qust.teachmask;
Import android.app.Activity;
Import Android.graphics.PixelFormat;
Import Android.os.Bundle;
Import android.view.Gravity;
Import Android.view.View;
Import Android.view.View.OnClickListener;
Import Android.view.WindowManager;
Import Android.view.WindowManager.LayoutParams;
Import Android.widget.ImageView;
Import Android.widget.ImageView.ScaleType;
public class Mainactivity extends activity {private ImageView img;
Private WindowManager WindowManager;
@Override protected void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
Setcontentview (R.layout.activity_main);
WindowManager = Getwindowmanager ();
Dynamic initialization layer img = new ImageView (this);
Img.setlayoutparams (New Layoutparams (Android.view.ViewGroup.LayoutParams.MATCH_PARENT,
Android.view.ViewGroup.LayoutParams.MATCH_PARENT));
Img.setscaletype (SCALETYPE.FIT_XY);
Img.setimageresource (R.drawable.guide); Set Layoutparams parameter Layoutparams params = new windowmanager.laYoutparams (); Set the type of display, type_phone refers to the phone will be overwritten, other times will be on the front end, the display position under Statebar, other more values please consult the documentation Params.type =
WindowManager.LayoutParams.TYPE_PHONE;
Set display format Params.format = pixelformat.rgba_8888; Set Alignment params.gravity = Gravity.left |
Gravity.top;
Set width High params.width = Screenutils.getscreenwidth (this);
Params.height = Screenutils.getscreenheight (this);
Add to the current Window Windowmanager.addview (IMG, params); After clicking the layer, remove the layer Img.setonclicklistener (new Onclicklistener () {@Override public void OnClick (View arg0) {windowmanage
R.removeview (IMG);
}
}); }
}
This article is not original, reproduced in: http://blog.csdn.net/zhaokaiqiang1992
The above is a small series to introduce the Android Desktop Suspension window, mask effect example code, I hope to help!