判断状态栏是否显示以及获取状态栏高度的方法,及工具类列子
https://www.2cto.com/kf/201703/605854.html
如上述网址所述,有两种通用的方法。第二中方法其实没有必要新建一个服务。
其实可以直接这样用:
优化方案一:
1、onCreate的时候:
private void initStatusBarHelperView() {
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mStatusBarHelperView = new View(mContext);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
lp.gravity = Gravity.LEFT | Gravity.TOP;
lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
lp.format = PixelFormat.TRANSLUCENT;
wm.addView(mStatusBarHelperView, lp);
}
2、onDestory的时候:
public void removeStatusBarHelperView() {
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
wm.removeView(mStatusBarHelperView);
mStatusBarHelperView = null;
}
3、需要高度的时候:
public int getStatusBarHeight() {
int[] windowParams = new int[2];
int[] screenParams = new int[2];
mStatusBarHelperView.getLocationInWindow(windowParams);
mStatusBarHelperView.getLocationOnScreen(screenParams);
return screenParams[1] - windowParams[1];
}
上面的方法亲测已经满足。
优化方案二:
考虑到如果在服务中,只在destory才remove,新建的view一直存在也不太好。所以在onstart和onpusue调用对应的方法比较合适,但是如果频繁的调用又有性能问题,故最终采用在remove的时候延迟执行。最后写了一个工具类,直接调用如下三个方法即可:
StatusBarHelper.getInstance().getStatusBarHeight()
StatusBarHelper.getInstance().addStatusBarHelperView();
StatusBarHelper.getInstance().removeStatusBarHelperView();
工具类如下:
package com.smartisanos.ime.util;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import com.smartisanos.ime.IMEApp;
public class StatusBarHelper {
private Context mContext;
private View mStatusBarHelperView;
private static StatusBarHelper mStatusBarHelper = new StatusBarHelper();
private static final int MSG_INIT_STATUS_BAR = 1;
private static final int MSG_REMOVE_STATUS_BAR = 2;
private static final long MSG_REMOVE_DELAY_TIME = 500L;
private Handler mStatusBarHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_INIT_STATUS_BAR:
mStatusBarHandler.removeMessages(MSG_REMOVE_STATUS_BAR);
initStatusBarHelperView();
break;
case MSG_REMOVE_STATUS_BAR:
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
wm.removeView(mStatusBarHelperView);
mStatusBarHelperView = null;
break;
}
}
};
private StatusBarHelper() {
mContext = IMEApp.getContext();
}
public static StatusBarHelper getInstance() {
return mStatusBarHelper;
}
/* //由于在本类的构造方法中并没有耗时操作,所以不需要在getInstance()中进行new操作,可以直接在定义变量时直接new。故没有用下面的方法
public static StatusBarHelper getInstance() {
if (mStatusBarHelper == null) {
mStatusBarHelper = new StatusBarHelper();
}
return mStatusBarHelper;
}
*/
private void initStatusBarHelperView() {
if (mStatusBarHelperView != null) {
return;
}
WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
mStatusBarHelperView = new View(mContext);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
lp.gravity = Gravity.LEFT | Gravity.TOP;
lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
lp.format = PixelFormat.TRANSLUCENT;
wm.addView(mStatusBarHelperView, lp);
}
public void addStatusBarHelperView() {
Message message = mStatusBarHandler.obtainMessage(StatusBarHelper.MSG_INIT_STATUS_BAR);
mStatusBarHandler.sendMessage(message);
}
public void removeStatusBarHelperView() {
Message message = mStatusBarHandler.obtainMessage(StatusBarHelper.MSG_REMOVE_STATUS_BAR);
mStatusBarHandler.sendMessageDelayed(message, StatusBarHelper.MSG_REMOVE_DELAY_TIME);
}
public int getStatusBarHeight() {
if (mStatusBarHelperView == null) {
return 0;
}
int[] windowParams = new int[2];
int[] screenParams = new int[2];
mStatusBarHelperView.getLocationInWindow(windowParams);
mStatusBarHelperView.getLocationOnScreen(screenParams);
return screenParams[1] - windowParams[1];
}
}
20190806更新
注意:适配8.0时,需initStatusBarHelperView()方法中,要修改两处
1、要给window设置不获取焦点:FLAG_NOT_FOCUSABLE
2、Android8.0时,要用TYPE_APPLICATION_OVERLAY
1 private void initStatusBarHelperView() { 2 boolean isShown = ServiceManager.getInstance().getInputMethodService().isInputViewShown(); 3 Log.d(TAG, "initStatusBarHelperView: isShown="+isShown+" mStatusBarHelperView="+mStatusBarHelperView); 4 if (mStatusBarHelperView != null || !isShown) { 5 return; 6 } 7 WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 8 mStatusBarHelperView = new View(mContext); 9 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10 lp.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 11 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 12 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 13 lp.gravity = Gravity.LEFT | Gravity.TOP; 14 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 15 lp.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; 16 } else { 17 lp.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY; 18 } 19 lp.format = PixelFormat.TRANSLUCENT; 20 lp.width = 1; 21 wm.addView(mStatusBarHelperView, lp); 22 }
后来的优化代码见博客:
https://www.cnblogs.com/longjunhao/p/9055087.html
我的GitHub:https://github.com/lelelongwang

浙公网安备 33010602011771号