目录
在Android手机中页面对状态栏做了侵入式展示,但是弹窗的时候,PopupWindow并没有进入状态栏,导致状态栏别具一格的颜色。
解决方法二:把状态栏颜色改成与Toolbar颜色一致(假全屏)
解决方法三:以上代码只是假性实现了全屏,但是针对那些侧拉,下拉的,或者状态栏中需要显示popupwindow 内容的,可能就不行了
在Android手机中页面对状态栏做了侵入式展示,但是弹窗的时候,PopupWindow并没有进入状态栏,导致状态栏别具一格的颜色。
解决方法一、适用于大多数手机,但是小米新机型例外
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
popupWindow.setIsLaidOutInScreen(true);
} else {
fitPopupWindowOverStatusBar(popupWindow, true);
}
public static void fitPopupWindowOverStatusBar(PopupWindow mPopupWindow, boolean needFullScreen) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
Field mLayoutInScreen = PopupWindow.class.getDeclaredField("mLayoutInScreen");
mLayoutInScreen.setAccessible(needFullScreen);
mLayoutInScreen.set(mPopupWindow, needFullScreen);
} catch (NoSuchFieldException | IllegalAccessException e) {
Log.i("DeviceInfoPopupwindow", "" + e.toString());
e.printStackTrace();
}
}
}
我手中用的红米Note7,状态栏用了N种方法都没法被遮住,很显眼的一条高亮的色泽。
解决方法二:把状态栏颜色改成与Toolbar颜色一致
因为我的Popupwindow 从底部弹出,上半部分是半透明的样式,所以我针对小米手机设置了一下状态栏色颜色,为那个被阴影遮挡之后的颜色,以下为效果
我手中的红米NOTE 7跟其他小米手机还不太一样,他有一条黑线,是因为popupwindow高度进入了状态栏四个像素(可能属于MIUI 的BUG)
针对这个机型可以专门设置一下高度 在popupwindow布局文件中距离顶部距离2dp就好了
View view = View.inflate(activity, R.layout.my_dialog_run_mode2, null);
PopupWindow popupWindow = new PopupWindow(view, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT, false);
popupWindow.setTouchable(true);
popupWindow.setBackgroundDrawable(new BitmapDrawable(activity.getResources(), (Bitmap) null));
popupWindow.setAnimationStyle(R.style.popupAnimation);
popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
try {
if (Rom.isMiui()) {
if (activity instanceof BaseActivity) {
WindowsUtil.setStatusBarColor(activity, ((BaseActivity) activity).lastStatusBarTintColor);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
if (Rom.isMiui()) {
WindowsUtil.setStatusBarColor(activity, R.color.alph_status);
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
popupWindow.setIsLaidOutInScreen(true);
} else {
fitPopupWindowOverStatusBar(popupWindow, true);
}
}
popupWindow.showAtLocation(view, Gravity.BOTTOM, 0, 0);
--------下面是判断机型的代码
import android.os.Build;
import android.text.TextUtils;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* @author: jjf
* @date: 2019/8/28
* @describe:
*/
public class Rom {
private static final String TAG = "Rom";
public static final String ROM_MIUI = "MIUI";
public static final String ROM_EMUI = "EMUI";
public static final String ROM_FLYME = "FLYME";//魅族
public static final String ROM_OPPO = "OPPO";
public static final String ROM_SMARTISAN = "SMARTISAN";
public static final String ROM_VIVO = "VIVO";
public static final String ROM_QIKU = "QIKU";
public static final String ROM_NOKIA = "Nokia";//诺基亚
public static final String ROM_SAMSUNG = "samsung";//诺基亚
private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";
private static final String KEY_VERSION_MIUI = "ro.miui.ui.version.name";
private static final String KEY_VERSION_EMUI = "ro.build.version.emui";
private static final String KEY_VERSION_OPPO = "ro.build.version.opporom";
private static final String KEY_VERSION_SMARTISAN = "ro.smartisan.version";
private static final String KEY_VERSION_VIVO = "ro.vivo.os.version";
private static String sName;
private static String sVersion;
/**
* 华为
* @return
*/
public static boolean isEmui() {
return check(ROM_EMUI);
}
/**
* 小米
* @return
*/
public static boolean isMiui() {
return check(ROM_MIUI);
}
public static boolean isVivo() {
return check(ROM_VIVO);
}
public static boolean isOppo() {
return check(ROM_OPPO);
}
public static boolean isFlyme() {
return check(ROM_FLYME);
}
public static boolean isNokia() {
return check(ROM_NOKIA);
}
public static boolean is360() {
return check(ROM_QIKU) || check("360");
}
public static boolean isSmartisan() {
return check(ROM_SMARTISAN);
}
public static String getName() {
if (sName == null) {
check("");
}
return sName;
}
public static String getVersion() {
if (sVersion == null) {
check("");
}
return sVersion;
}
public static boolean check(String rom) {
if (sName != null) {
return sName.equalsIgnoreCase(rom);
}
if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_MIUI))) {
sName = ROM_MIUI;
} else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_EMUI))) {
sName = ROM_EMUI;
} else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_OPPO))) {
sName = ROM_OPPO;
} else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_VIVO))) {
sName = ROM_VIVO;
} else if (!TextUtils.isEmpty(sVersion = getProp(KEY_VERSION_SMARTISAN))) {
sName = ROM_SMARTISAN;
} else {
sVersion = Build.DISPLAY;
if (sVersion.toUpperCase().contains(ROM_FLYME)) {
sName = ROM_FLYME;
} else {
sVersion = Build.UNKNOWN;
sName = Build.MANUFACTURER.toUpperCase();
}
}
return sName.equals(rom);
}
public static String getProp(String name) {
String line = null;
BufferedReader input = null;
try {
Process p = Runtime.getRuntime().exec("getprop " + name);
input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
line = input.readLine();
input.close();
} catch (IOException ex) {
Log.e(TAG, "Unable to read prop " + name, ex);
return null;
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return line;
}
}
------下面是Window工具类
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.os.Build;
import android.os.IBinder;
import android.provider.Settings;
import android.support.annotation.RequiresApi;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.DisplayCutout;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import com.readystatesoftware.systembartint.SystemBarTintManager;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.util.List;
import java.util.logging.Logger;
import anet.channel.util.Utils;
/**
* @author: jjf
* @date: 2018/7/25
* @describe:UI工具类
*/
public class WindowsUtil {
/**
* 获取屏幕宽度
*/
public static int WindowsWidth(Activity context) {
WindowManager manager = context.getWindowManager();
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
DisplayMetrics m = MainApplication.getAppContext().getResources().getDisplayMetrics();
return m.widthPixels;
}
/**
* 获取屏幕宽度
*/
public static int WindowsWidth_dp(Activity context) {
WindowManager manager = context.getWindowManager();
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
int screenWidth = (int) (outMetrics.widthPixels / outMetrics.density + 0.5f); // 屏幕宽度(dp)
return screenWidth;
}
public void getAndroiodScreenProperty(Activity context) {
WindowManager wm = (WindowManager) context.getWindowManager();
DisplayMetrics dm = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(dm);
int width = dm.widthPixels; // 屏幕宽度(像素)
int height = dm.heightPixels; // 屏幕高度(像素)
float density = dm.density; // 屏幕密度(0.75 / 1.0 / 1.5)
int densityDpi = dm.densityDpi; // 屏幕密度dpi(120 / 160 / 240)
// 屏幕宽度算法:屏幕宽度(像素)/屏幕密度
int screenWidth = (int) (width / density); // 屏幕宽度(dp)
int screenHeight = (int) (height / density);// 屏幕高度(dp)
}
/**
* 获取屏幕高度
*/
public static int WindowsHeight(Activity context) {
WindowManager manager = context.getWindowManager();
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.heightPixels;
}
//单位dp值转化为单位px值
public static int dp2px(int dpVal) {
return (int) dp2px((float) dpVal);
}
//单位dp值转化为单位px值
public static float dp2px(float dpVal) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, MainApplication.getAppContext().getResources().getDisplayMetrics());
}
public static float dp2px(Activity activity, float dpVal) {
WindowManager manager = activity.getWindowManager();
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
float px1 = (dpVal * outMetrics.scaledDensity + 0.5f);
float px2 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, MainApplication.getAppContext().getResources().getDisplayMetrics());
float px3 = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, activity.getResources().getDisplayMetrics());
LogUtil.I(TAG, "px1= " + px1 + " px2= " + px2 + " px3= " + px3);
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
dpVal, MainApplication.getAppContext().getResources().getDisplayMetrics());
}
public static int px2dip(Activity context, float pxValue) {
WindowManager manager = context.getWindowManager();
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
final float scale1 = outMetrics.density;//
final float scale3 = MainApplication.getAppContext().getResources().getDisplayMetrics().density;
int dp1 = (int) (pxValue / scale1 + 0.5f);
int dp3 = (int) (pxValue / scale3 + 0.5f);
LogUtil.I(TAG, "dp1" + dp1 + " dp3" + dp3);
// getNotchParams(context);
return dp1;
// return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
// dpVal, ScreenAdapter.lastMetrics); pxValue
}
/**
* 将px值转换为sp值,保证文字大小不变
*
* @param pxValue
* @return
*/
public static int px2sp(Activity activity, float pxValue) {
WindowManager manager = activity.getWindowManager();
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
final float fontScale = outMetrics.scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
/**
* 将sp值转换为px值,保证文字大小不变
*
* @param spValue
* @return
*/
public static int sp2px(Activity activity, float spValue) {
WindowManager manager = activity.getWindowManager();
DisplayMetrics outMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(outMetrics);
final float fontScale = outMetrics.scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
/**
* 根据传入控件的坐标和用户的焦点坐标,判断是否隐藏键盘,如果点击的位置在控件内,则不隐藏键盘
*
* @param view 控件view
* @param event 焦点位置
* @return 是否隐藏
*/
public static void hideKeyboard(MotionEvent event, View view,
Activity activity) {
WeakReference<Activity> weakReference = new WeakReference<Activity>(activity);
try {
if (view != null && view instanceof EditText) {
int[] location = {0, 0};
view.getLocationInWindow(location);
int left = location[0], top = location[1], right = left
+ view.getWidth(), bootom = top + view.getHeight();
// 判断焦点位置坐标是否在空间内,如果位置在控件外,则隐藏键盘
if (event.getRawX() < left || event.getRawX() > right
|| event.getY() < top || event.getRawY() > bootom) {
// 隐藏键盘
IBinder token = view.getWindowToken();
if (weakReference.get() != null) {
InputMethodManager inputMethodManager = (InputMethodManager) weakReference.get()
.getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(token,
InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
} catch (Exception e) {
LogUtil.I(TAG, "hideKeyboard() e=" + e.toString());
}
}
private static String TAG = "WindowUtil";
public static void getNotchParams(Activity activity) {
final View decorView = activity.getWindow().getDecorView();
decorView.post(new Runnable() {
// @RequiresApi(api = Build.VERSION_CODES.P)
@Override
public void run() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
WindowInsets rootWindowInsets = decorView.getRootWindowInsets();
if (rootWindowInsets == null) {
LogUtil.I("TAG", "rootWindowInsets为空了");
return;
}
DisplayCutout displayCutout = rootWindowInsets.getDisplayCutout();
if (displayCutout == null) {
LogUtil.I("TAG", "displayCutout为空了");
return;
}
LogUtil.I("TAG", "安全区域距离屏幕左边的距离 SafeInsetLeft:" + displayCutout.getSafeInsetLeft());
LogUtil.I("TAG", "安全区域距离屏幕右部的距离 SafeInsetRight:" + displayCutout.getSafeInsetRight());
LogUtil.I("TAG", "安全区域距离屏幕顶部的距离 SafeInsetTop:" + displayCutout.getSafeInsetTop());
LogUtil.I("TAG", "安全区域距离屏幕底部的距离 SafeInsetBottom:" + displayCutout.getSafeInsetBottom());
List<Rect> rects = displayCutout.getBoundingRects();
if (rects.size() == 0) {
LogUtil.I("TAG", "不是刘海屏");
} else {
LogUtil.I("TAG", "刘海屏数量:" + rects.size());
for (Rect rect : rects) {
LogUtil.I("TAG", "刘海屏区域:" + rect);
}
}
}
}
});
}
/**
* 获取状态栏高度
*
* @param context
* @return
*/
public static int getStatusBarHeight(Context context) {
try {
Resources resources = context.getResources();
int resourceId = resources.getIdentifier("status_bar_height", "dimen", "android");
int height = resources.getDimensionPixelSize(resourceId);
return height;
} catch (Exception e) {
return 0;
}
}
/**
* 设置状态栏颜色
*
* @param activity
* @param color
*/
public static void setStatusBarColor(Activity activity, int color) {
try {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
SystemBarTintManager tintManager = new SystemBarTintManager(activity);
tintManager.setStatusBarTintColor(activity.getResources().getColor(color));//R.color.app_main_color
tintManager.setStatusBarTintEnabled(true);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 更改状态栏 文本 颜色
*
* @param activity
* @param dark
*/
public static void setStatusBarTextColor(Activity activity, boolean dark) {
View decor = activity.getWindow().getDecorView();
if (dark) {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
}
}
/**
* @param activity
* @param color
*/
public static void setNavigationBarColor(Activity activity, int color) {
try {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
SystemBarTintManager tintManager = new SystemBarTintManager(activity);
if (ScreenUtils.getBottomStatusHeight(activity.getApplicationContext()) > 0) {
tintManager.setNavigationBarTintColor(activity.getResources().getColor(color));
tintManager.setNavigationBarTintEnabled(true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 是否隐藏了导航键
*
* @param context
* @return
*/
public static boolean isNavBarHide(Context context) {
try {
String brand = Build.BRAND;
// 这里做判断主要是不同的厂商注册的表不一样
if (!StringUtils.isNullData(brand) && (Rom.isVivo() || Rom.isOppo())) {
return Settings.Secure.getInt(context.getContentResolver(), getDeviceForceName(), 0) != 0;
} else if (!StringUtils.isNullData(brand) && Rom.isNokia()) {
//甚至 nokia 不同版本注册的表不一样, key 还不一样。。。
return Settings.Secure.getInt(context.getContentResolver(), "swipe_up_to_switch_apps_enabled", 0) == 1
|| Settings.System.getInt(context.getContentResolver(), "navigation_bar_can_hiden", 0) != 0;
} else
return Settings.Global.getInt(context.getContentResolver(), getDeviceForceName(), 0) != 0;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/**
* 各个手机厂商注册导航键相关的 key
*
* @return
*/
public static String getDeviceForceName() {
String brand = Build.BRAND;
if (StringUtils.isNullData(brand))
return "navigationbar_is_min";
if (brand.equalsIgnoreCase("HUAWEI") || "HONOR".equals(brand)) {
return "navigationbar_is_min";
} else if (Rom.isMiui()||Rom.check("XIAOMI")) {
return "force_fsg_nav_bar";
} else if (Rom.isVivo()) {
return "navigation_gesture_on";
} else if (Rom.isOppo()) {
return "hide_navigationbar_enable";
} else if (Rom.check("samsung")) {
return "navigationbar_hide_bar_enabled";
} else if (brand.equalsIgnoreCase("Nokia")) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
return "navigation_bar_can_hiden";
} else {
return "swipe_up_to_switch_apps_enabled";
}
} else {
return "navigationbar_is_min";
}
}
}
解决方法三、以上代码只是假性实现了全屏,但是针对那些侧拉,下拉的,或者状态栏中需要显示popupwindow 内容的,可能就不行了
期待大佬来补充!