If you want to realize a floating window displayed on the desktop, you can no longer use Dialog
, PopupWindow
, etc. They are basically displayed on it. If you want to realize the floating window effect displayed on the desktop, you need to use it realize it.Toast
Activity
WindowManager
renderings
Implemented using WindowManager
- Add a floating window:
sys_view = new SmallWindowView(mContext);
sys_view.setText("50%");
sys_view.setOnTouchListener(this);
windowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
int screenWidth = 0, screenHeight = 0;
if (windowManager != null) {
//获取屏幕的宽和高
Point point = new Point();
windowManager.getDefaultDisplay().getSize(point);
screenWidth = point.x;
screenHeight = point.y;
layoutParams = new WindowManager.LayoutParams();
// layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
// layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
layoutParams.width = 200;
layoutParams.height = 200;
//设置type
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//26及以上必须使用TYPE_APPLICATION_OVERLAY @deprecated TYPE_PHONE
layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
}
//设置flags
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
layoutParams.gravity = Gravity.START | Gravity.TOP;
//背景设置成透明
layoutParams.format = PixelFormat.TRANSPARENT;
layoutParams.x = screenWidth;
layoutParams.y = screenHeight / 2;
//将View添加到屏幕上
windowManager.addView(sys_view, layoutParams);
}
- Update the floating window position:
windowManager.updateViewLayout(sys_view, layoutParams);
- Close the floating window:
windowManager.removeView(sys_view);
Through the above code, a desktop floating window function can be realized.
Note : In
6.0
the above, you need toManifest.xml
declare the permission in<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
and dynamically judge the permission when you open the floating window. If you don’t have this permission, you need to jump to the settings page to set it. See the description of the official document:
analyze
1. Add floating window: By Context.getSystemService(Context.WINDOW_SERVICE)
obtaining one WindowManager
( hereinafter referred to as VM ), VM
it is the entrance of external access Window
, Activity
, Dialog
, Toast
and other views are attached to Window
it, Window
and it is View
the direct manager, VM
inherited from ViewManager
, its add, refresh, delete methods Also from ViewManager
:
public interface ViewManager
{
public void addView(View view, ViewGroup.LayoutParams params);
public void updateViewLayout(View view, ViewGroup.LayoutParams params);
public void removeView(View view);
}
VM
There is a static inner class WindowManager.LayoutParams
, Window
each property of which is set in this inner class:
- If LayoutParams.TYPE
TargetSdkVersion<26
, then can be used directlyLayoutParams.TYPE_PHONE
orLayoutParams.TYPE_SYSTEM_ALERT
, whenTargetSdkVersion>=26
,TYPE_PHONE
andTYPE_SYSTEM_ALERT
have been deprecated, need to useTYPE_APPLICATION_OVERLAY
to identifyTYPE
. - The attributes
FLAGS
represented by LayoutParams.FLAGS can be controlled through the display characteristics, and several commonly used characteristics: : Using this flag, the click event can be transmitted to the area other than the floating window, otherwise the event will not be received in other areas. : Indicates that the floating window does not need to get the focus, nor does it need to get various input events, and the events will be passed directly to the lower layer with focus : This mode can be displayed on the lock screen interfaceWindow
FLAGS
Window
LayoutParams.FLAG_NOT_TOUCH_MODAL
Window
LayoutParams.FLAG_NOT_FOCUSABLE
Window
Window
LayoutParams.FLAG_SHOW_WHEN_LOCKED
Window
- LayoutParams.FORMAT The background format of the floating window Window, generally set to
PixelFormat.TRANSPARENT
transparent - LayoutParams.X & LayoutParams.Y The coordinate value of the floating window
Window
on the screen, which can be usedX&Y
to refreshWindow
the position on the screen according to the value - LayoutParams.Width & LayoutParams.Height
Window
The width and height of the floating window
2. Update the position of the floating window: Update the value of and View
in OnTouchEvent
or in and reset the position of the floating window Window on the screen, as follows:OnTouch
layoutParams.x
layoutParams.y
windowManager.updateViewLayout()
@Override
public boolean onTouch(View v, MotionEvent event) {
int mInScreenX = (int) event.getRawX();
int mInScreenY = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastX = (int) event.getRawX();
mLastY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
layoutParams.x += mInScreenX - mLastX;
layoutParams.y += mInScreenY - mLastY;
mLastX = mInScreenX;
mLastY = mInScreenY;
windowManager.updateViewLayout(sys_view, layoutParams);
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
3. Delete the floating window: It is relatively simple to delete, just call directly to windowManager.removeView(view)
delete view
from itWindow
.
question
When 6.0以上
using it, you need to dynamically apply for the permission of the floating window, as follows:
//判断有没有悬浮窗权限,没有去申请
if(!Settings.canDrawOverlays(context)){
Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + context.getPackageName()));
context.startActivityForResult(intent, REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE:
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return;
if (!WindowUtil.canOverDraw(this)) {
toast("悬浮窗权限未开启,请在设置中手动打开");
return;
}
WindowController.getInstance().showThumbWindow();
break;
}
}
By Settings.canDrawOverlays(context)
judging whether there is a floating window permission, if not, jump to the setting page to set it up, and onActivityResult ()
get the application result in it, it seems perfect, but in the actual test, it is found that there is a problem with the mobile phone above 8.0, even in the setting Agree to the permissions in the 8.0 mobile phone, Settings.canDrawOverlays(context)
it always returns false
, but when the page is closed and the method is called again, it returns again true
, and it feels that there is a certain delay. google
After a while, I found that other people have also encountered this google
problem bug
. .
If you want the full version of Android learning materials, please click to get it for free