Android 水滴屏、全屏适配

ops/2024/9/20 7:16:42/ 标签: android

Android 水滴屏、全屏适配

何谓刘海屏?何谓水滴屏?

全面屏、水滴屏

上述两种屏幕都可以统称为刘海屏,不过对于右侧较小的刘海,业界一般称为水滴屏或美人尖。

目前国内流行的手机厂商主要有:vivo、oppo、华为、小米。各厂商对刘海屏的适配都大不相同,各自有各自对刘海屏的适配API,具体的适配方法可以阅读相应的官网:

VIVO: https://dev.vivo.com.cn/documentCenter/doc/103

OPPO: https://open.oppomobile.com/wiki/doc#id=10159

小米: https://dev.mi.com/console/doc/detail?pId=1293

华为: https://developer.huawei.com/consumer/cn/devservice/doc/50114?from=timeline

下面介绍几种适配方法:

1.StatusBarUtil工具类

1.1 StatusBarUtil工具类

public class StatusBarUtil {//透明度public static final int DEFAULT_STATUS_BAR_ALPHA = 112;private static final int FAKE_STATUS_BAR_VIEW_ID = R.id.statusbarutil_fake_status_bar_view;private static final int FAKE_TRANSLUCENT_VIEW_ID = R.id.statusbarutil_translucent_view;private static final int TAG_KEY_HAVE_SET_OFFSET = -123;/*** 设置状态栏颜色** @param activity 需要设置的 activity* @param color    状态栏颜色值*/public static void setColor(Activity activity, @ColorInt int color) {setColor(activity, color, DEFAULT_STATUS_BAR_ALPHA);}/*** 设置状态栏颜色** @param activity       需要设置的activity* @param color          状态栏颜色值* @param statusBarAlpha 状态栏透明度*/public static void setColor(Activity activity, @ColorInt int color, @IntRange(from = 0, to = 255) int statusBarAlpha) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);activity.getWindow().setStatusBarColor(calculateStatusColor(color, statusBarAlpha));} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);if (fakeStatusBarView != null) {if (fakeStatusBarView.getVisibility() == View.GONE) {fakeStatusBarView.setVisibility(View.VISIBLE);}fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));} else {decorView.addView(createStatusBarView(activity, color, statusBarAlpha));}setRootView(activity);}}/*** 为滑动返回界面设置状态栏颜色** @param activity 需要设置的activity* @param color    状态栏颜色值*/public static void setColorForSwipeBack(Activity activity, int color) {setColorForSwipeBack(activity, color, DEFAULT_STATUS_BAR_ALPHA);}/*** 为滑动返回界面设置状态栏颜色** @param activity       需要设置的activity* @param color          状态栏颜色值* @param statusBarAlpha 状态栏透明度*/public static void setColorForSwipeBack(Activity activity, @ColorInt int color,@IntRange(from = 0, to = 255) int statusBarAlpha) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {ViewGroup contentView = ((ViewGroup) activity.findViewById(android.R.id.content));View rootView = contentView.getChildAt(0);int statusBarHeight = getStatusBarHeight(activity);if (rootView != null && rootView instanceof CoordinatorLayout) {final CoordinatorLayout coordinatorLayout = (CoordinatorLayout) rootView;if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {coordinatorLayout.setFitsSystemWindows(false);contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));boolean isNeedRequestLayout = contentView.getPaddingTop() < statusBarHeight;if (isNeedRequestLayout) {contentView.setPadding(0, statusBarHeight, 0, 0);coordinatorLayout.post(new Runnable() {@Overridepublic void run() {coordinatorLayout.requestLayout();}});}} else {coordinatorLayout.setStatusBarBackgroundColor(calculateStatusColor(color, statusBarAlpha));}} else {contentView.setPadding(0, statusBarHeight, 0, 0);contentView.setBackgroundColor(calculateStatusColor(color, statusBarAlpha));}setTransparentForWindow(activity);}}/*** 设置状态栏纯色 不加半透明效果** @param activity 需要设置的 activity* @param color    状态栏颜色值*/public static void setColorNoTranslucent(Activity activity, @ColorInt int color) {setColor(activity, color, 0);}/*** 设置状态栏纯色 不加半透明效果 字体为黑色** @param activity 需要设置的 activity* @param color    状态栏颜色值*/public static void setColorNoTranslucentLightMode(Activity activity, @ColorInt int color) {setColor(activity, color, 0);//setLightMode(activity);}/*** 设置状态栏颜色(5.0以下无半透明效果,不建议使用)** @param activity 需要设置的 activity* @param color    状态栏颜色值*/@Deprecatedpublic static void setColorDiff(Activity activity, @ColorInt int color) {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {return;}transparentStatusBar(activity);ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);// 移除半透明矩形,以免叠加View fakeStatusBarView = contentView.findViewById(FAKE_STATUS_BAR_VIEW_ID);if (fakeStatusBarView != null) {if (fakeStatusBarView.getVisibility() == View.GONE) {fakeStatusBarView.setVisibility(View.VISIBLE);}fakeStatusBarView.setBackgroundColor(color);} else {contentView.addView(createStatusBarView(activity, color));}setRootView(activity);}/*** 使状态栏半透明* <p>* 适用于图片作为背景的界面,此时需要图片填充到状态栏** @param activity 需要设置的activity*/public static void setTranslucent(Activity activity) {setTranslucent(activity, DEFAULT_STATUS_BAR_ALPHA);}/*** 使状态栏半透明* <p>* 适用于图片作为背景的界面,此时需要图片填充到状态栏** @param activity       需要设置的activity* @param statusBarAlpha 状态栏透明度*/public static void setTranslucent(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {return;}setTransparent(activity);addTranslucentView(activity, statusBarAlpha);}/*** 针对根布局是 CoordinatorLayout, 使状态栏半透明* <p>* 适用于图片作为背景的界面,此时需要图片填充到状态栏** @param activity       需要设置的activity* @param statusBarAlpha 状态栏透明度*/public static void setTranslucentForCoordinatorLayout(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {return;}transparentStatusBar(activity);addTranslucentView(activity, statusBarAlpha);}/*** 设置状态栏全透明** @param activity 需要设置的activity*/public static void setTransparent(Activity activity) {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {return;}transparentStatusBar(activity);setRootView(activity);}/*** 使状态栏透明(5.0以上半透明效果,不建议使用)* <p>* 适用于图片作为背景的界面,此时需要图片填充到状态栏** @param activity 需要设置的activity*/@Deprecatedpublic static void setTranslucentDiff(Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// 设置状态栏透明activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);setRootView(activity);}}/*** 为DrawerLayout 布局设置状态栏变色** @param activity     需要设置的activity* @param drawerLayout DrawerLayout* @param color        状态栏颜色值*/public static void setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {setColorForDrawerLayout(activity, drawerLayout, color, DEFAULT_STATUS_BAR_ALPHA);}/*** 为DrawerLayout 布局设置状态栏颜色,纯色** @param activity     需要设置的activity* @param drawerLayout DrawerLayout* @param color        状态栏颜色值*/public static void setColorNoTranslucentForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {setColorForDrawerLayout(activity, drawerLayout, color, 0);}/*** 为DrawerLayout 布局设置状态栏颜色,纯色 字体为黑色** @param activity     需要设置的activity* @param drawerLayout DrawerLayout* @param color        状态栏颜色值*/public static void setColorNoTranslucentForDrawerLayoutLightMode(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {setColorForDrawerLayout(activity, drawerLayout, color, 0);setLightMode(activity);}/*** 为DrawerLayout 布局设置状态栏变色** @param activity       需要设置的activity* @param drawerLayout   DrawerLayout* @param color          状态栏颜色值* @param statusBarAlpha 状态栏透明度*/public static void setColorForDrawerLayout(Activity activity, DrawerLayout drawerLayout, @ColorInt int color,@IntRange(from = 0, to = 255) int statusBarAlpha) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);activity.getWindow().setStatusBarColor(Color.TRANSPARENT);} else {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}// 生成一个状态栏大小的矩形// 添加 statusBarView 到布局中ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);View fakeStatusBarView = contentLayout.findViewById(FAKE_STATUS_BAR_VIEW_ID);if (fakeStatusBarView != null) {if (fakeStatusBarView.getVisibility() == View.GONE) {fakeStatusBarView.setVisibility(View.VISIBLE);}fakeStatusBarView.setBackgroundColor(color);} else {contentLayout.addView(createStatusBarView(activity, color), 0);}// 内容布局不是 LinearLayout 时,设置padding topif (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {contentLayout.getChildAt(1).setPadding(contentLayout.getPaddingLeft(), getStatusBarHeight(activity) + contentLayout.getPaddingTop(),contentLayout.getPaddingRight(), contentLayout.getPaddingBottom());}// 设置属性setDrawerLayoutProperty(drawerLayout, contentLayout);addTranslucentView(activity, statusBarAlpha);}/*** 设置 DrawerLayout 属性** @param drawerLayout              DrawerLayout* @param drawerLayoutContentLayout DrawerLayout 的内容布局*/private static void setDrawerLayoutProperty(DrawerLayout drawerLayout, ViewGroup drawerLayoutContentLayout) {ViewGroup drawer = (ViewGroup) drawerLayout.getChildAt(1);drawerLayout.setFitsSystemWindows(false);drawerLayoutContentLayout.setFitsSystemWindows(false);drawerLayoutContentLayout.setClipToPadding(true);drawer.setFitsSystemWindows(false);}/*** 为DrawerLayout 布局设置状态栏变色(5.0以下无半透明效果,不建议使用)** @param activity     需要设置的activity* @param drawerLayout DrawerLayout* @param color        状态栏颜色值*/@Deprecatedpublic static void setColorForDrawerLayoutDiff(Activity activity, DrawerLayout drawerLayout, @ColorInt int color) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);// 生成一个状态栏大小的矩形ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);View fakeStatusBarView = contentLayout.findViewById(FAKE_STATUS_BAR_VIEW_ID);if (fakeStatusBarView != null) {if (fakeStatusBarView.getVisibility() == View.GONE) {fakeStatusBarView.setVisibility(View.VISIBLE);}fakeStatusBarView.setBackgroundColor(calculateStatusColor(color, DEFAULT_STATUS_BAR_ALPHA));} else {// 添加 statusBarView 到布局中contentLayout.addView(createStatusBarView(activity, color), 0);}// 内容布局不是 LinearLayout 时,设置padding topif (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {contentLayout.getChildAt(1).setPadding(0, getStatusBarHeight(activity), 0, 0);}// 设置属性setDrawerLayoutProperty(drawerLayout, contentLayout);}}/*** 为 DrawerLayout 布局设置状态栏透明** @param activity     需要设置的activity* @param drawerLayout DrawerLayout*/public static void setTranslucentForDrawerLayout(Activity activity, DrawerLayout drawerLayout) {setTranslucentForDrawerLayout(activity, drawerLayout, DEFAULT_STATUS_BAR_ALPHA);}/*** 为 DrawerLayout 布局设置状态栏透明** @param activity     需要设置的activity* @param drawerLayout DrawerLayout*/public static void setTranslucentForDrawerLayout(Activity activity, DrawerLayout drawerLayout,@IntRange(from = 0, to = 255) int statusBarAlpha) {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {return;}setTransparentForDrawerLayout(activity, drawerLayout);addTranslucentView(activity, statusBarAlpha);}/*** 为 DrawerLayout 布局设置状态栏透明** @param activity     需要设置的activity* @param drawerLayout DrawerLayout*/public static void setTransparentForDrawerLayout(Activity activity, DrawerLayout drawerLayout) {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {return;}if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);activity.getWindow().setStatusBarColor(Color.TRANSPARENT);} else {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);// 内容布局不是 LinearLayout 时,设置padding topif (!(contentLayout instanceof LinearLayout) && contentLayout.getChildAt(1) != null) {contentLayout.getChildAt(1).setPadding(0, getStatusBarHeight(activity), 0, 0);}// 设置属性setDrawerLayoutProperty(drawerLayout, contentLayout);}/*** 为 DrawerLayout 布局设置状态栏透明(5.0以上半透明效果,不建议使用)** @param activity     需要设置的activity* @param drawerLayout DrawerLayout*/@Deprecatedpublic static void setTranslucentForDrawerLayoutDiff(Activity activity, DrawerLayout drawerLayout) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// 设置状态栏透明activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);// 设置内容布局属性ViewGroup contentLayout = (ViewGroup) drawerLayout.getChildAt(0);contentLayout.setFitsSystemWindows(true);contentLayout.setClipToPadding(true);// 设置抽屉布局属性ViewGroup vg = (ViewGroup) drawerLayout.getChildAt(1);vg.setFitsSystemWindows(false);// 设置 DrawerLayout 属性drawerLayout.setFitsSystemWindows(false);}}/*** 为头部是 ImageView 的界面设置状态栏全透明** @param activity       需要设置的activity* @param needOffsetView 需要向下偏移的 View*/public static void setTransparentForImageView(Activity activity, View needOffsetView) {setTranslucentForImageView(activity, 0, needOffsetView);}/*** 为头部是 ImageView 的界面设置状态栏透明(使用默认透明度)** @param activity       需要设置的activity* @param needOffsetView 需要向下偏移的 View*/public static void setTranslucentForImageView(Activity activity, View needOffsetView) {setTranslucentForImageView(activity, DEFAULT_STATUS_BAR_ALPHA, needOffsetView);}/*** 为头部是 ImageView 的界面设置状态栏透明** @param activity       需要设置的activity* @param statusBarAlpha 状态栏透明度* @param needOffsetView 需要向下偏移的 View*/public static void setTranslucentForImageView(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha,View needOffsetView) {if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {return;}setTransparentForWindow(activity);addTranslucentView(activity, statusBarAlpha);if (needOffsetView != null) {Object haveSetOffset = needOffsetView.getTag(TAG_KEY_HAVE_SET_OFFSET);if (haveSetOffset != null && (Boolean) haveSetOffset) {return;}ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) needOffsetView.getLayoutParams();layoutParams.setMargins(layoutParams.leftMargin, layoutParams.topMargin + getStatusBarHeight(activity),layoutParams.rightMargin, layoutParams.bottomMargin);needOffsetView.setTag(TAG_KEY_HAVE_SET_OFFSET, true);}}/*** 为 fragment 头部是 ImageView 的设置状态栏透明** @param activity       fragment 对应的 activity* @param needOffsetView 需要向下偏移的 View*/public static void setTranslucentForImageViewInFragment(Activity activity, View needOffsetView) {setTranslucentForImageViewInFragment(activity, DEFAULT_STATUS_BAR_ALPHA, needOffsetView);}/*** 为 fragment 头部是 ImageView 的设置状态栏透明** @param activity       fragment 对应的 activity* @param needOffsetView 需要向下偏移的 View*/public static void setTransparentForImageViewInFragment(Activity activity, View needOffsetView) {setTranslucentForImageViewInFragment(activity, 0, needOffsetView);}/*** 为 fragment 头部是 ImageView 的设置状态栏透明** @param activity       fragment 对应的 activity* @param statusBarAlpha 状态栏透明度* @param needOffsetView 需要向下偏移的 View*/public static void setTranslucentForImageViewInFragment(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha,View needOffsetView) {setTranslucentForImageView(activity, statusBarAlpha, needOffsetView);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {clearPreviousSetting(activity);}}/*** 隐藏伪状态栏 View** @param activity 调用的 Activity*/public static void hideFakeStatusBarView(Activity activity) {ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);if (fakeStatusBarView != null) {fakeStatusBarView.setVisibility(View.GONE);}View fakeTranslucentView = decorView.findViewById(FAKE_TRANSLUCENT_VIEW_ID);if (fakeTranslucentView != null) {fakeTranslucentView.setVisibility(View.GONE);}}@TargetApi(Build.VERSION_CODES.M)public static void setLightMode(Activity activity) {setMIUIStatusBarDarkIcon(activity, true);setMeizuStatusBarDarkIcon(activity, true);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);}}@TargetApi(Build.VERSION_CODES.M)public static void setDarkMode(Activity activity) {setMIUIStatusBarDarkIcon(activity, false);setMeizuStatusBarDarkIcon(activity, false);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);}}/*** 修改 MIUI V6  以上状态栏颜色*/private static void setMIUIStatusBarDarkIcon(@NonNull Activity activity, boolean darkIcon) {Class<? extends Window> clazz = activity.getWindow().getClass();try {@SuppressLint("PrivateApi")Class<?> layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");int darkModeFlag = field.getInt(layoutParams);Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);extraFlagField.invoke(activity.getWindow(), darkIcon ? darkModeFlag : 0, darkModeFlag);} catch (Exception e) {//e.printStackTrace();}}/*** 修改魅族状态栏字体颜色 Flyme 4.0*/private static void setMeizuStatusBarDarkIcon(@NonNull Activity activity, boolean darkIcon) {try {WindowManager.LayoutParams lp = activity.getWindow().getAttributes();Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");darkFlag.setAccessible(true);meizuFlags.setAccessible(true);int bit = darkFlag.getInt(null);int value = meizuFlags.getInt(lp);if (darkIcon) {value |= bit;} else {value &= ~bit;}meizuFlags.setInt(lp, value);activity.getWindow().setAttributes(lp);} catch (Exception e) {//e.printStackTrace();}}///@TargetApi(Build.VERSION_CODES.KITKAT)private static void clearPreviousSetting(Activity activity) {ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView();View fakeStatusBarView = decorView.findViewById(FAKE_STATUS_BAR_VIEW_ID);if (fakeStatusBarView != null) {decorView.removeView(fakeStatusBarView);ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);rootView.setPadding(0, 0, 0, 0);}}/*** 添加半透明矩形条** @param activity       需要设置的 activity* @param statusBarAlpha 透明值*/private static void addTranslucentView(Activity activity, @IntRange(from = 0, to = 255) int statusBarAlpha) {ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);View fakeTranslucentView = contentView.findViewById(FAKE_TRANSLUCENT_VIEW_ID);if (fakeTranslucentView != null) {if (fakeTranslucentView.getVisibility() == View.GONE) {fakeTranslucentView.setVisibility(View.VISIBLE);}fakeTranslucentView.setBackgroundColor(Color.argb(statusBarAlpha, 0, 0, 0));} else {contentView.addView(createTranslucentStatusBarView(activity, statusBarAlpha));}}/*** 生成一个和状态栏大小相同的彩色矩形条** @param activity 需要设置的 activity* @param color    状态栏颜色值* @return 状态栏矩形条*/private static View createStatusBarView(Activity activity, @ColorInt int color) {return createStatusBarView(activity, color, 0);}/*** 生成一个和状态栏大小相同的半透明矩形条** @param activity 需要设置的activity* @param color    状态栏颜色值* @param alpha    透明值* @return 状态栏矩形条*/private static View createStatusBarView(Activity activity, @ColorInt int color, int alpha) {// 绘制一个和状态栏一样高的矩形View statusBarView = new View(activity);LinearLayout.LayoutParams params =new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));statusBarView.setLayoutParams(params);statusBarView.setBackgroundColor(calculateStatusColor(color, alpha));statusBarView.setId(FAKE_STATUS_BAR_VIEW_ID);return statusBarView;}/*** 设置根布局参数*/private static void setRootView(Activity activity) {ViewGroup parent = (ViewGroup) activity.findViewById(android.R.id.content);for (int i = 0, count = parent.getChildCount(); i < count; i++) {View childView = parent.getChildAt(i);if (childView instanceof ViewGroup) {childView.setFitsSystemWindows(true);((ViewGroup) childView).setClipToPadding(true);}}}/*** 设置透明*/private static void setTransparentForWindow(Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {activity.getWindow().setStatusBarColor(Color.TRANSPARENT);activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}}/*** 使状态栏透明*/@TargetApi(Build.VERSION_CODES.KITKAT)private static void transparentStatusBar(Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);activity.getWindow().setStatusBarColor(Color.TRANSPARENT);} else {activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}}/*** 创建半透明矩形 View** @param alpha 透明值* @return 半透明 View*/private static View createTranslucentStatusBarView(Activity activity, int alpha) {// 绘制一个和状态栏一样高的矩形View statusBarView = new View(activity);LinearLayout.LayoutParams params =new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity));statusBarView.setLayoutParams(params);statusBarView.setBackgroundColor(Color.argb(alpha, 0, 0, 0));statusBarView.setId(FAKE_TRANSLUCENT_VIEW_ID);return statusBarView;}/*** 获取状态栏高度** @param context context* @return 状态栏高度*/public static int getStatusBarHeight(Context context) {// 获得状态栏高度int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");return context.getResources().getDimensionPixelSize(resourceId);}/**** 只能作用于activity*/public static void setTaskBarColored(Activity context, int color) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {Window w = context.getWindow();w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//status bar heightint statusBarHeight = getStatusBarHeight(context);View view = new View(context);view.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));view.getLayoutParams().height = statusBarHeight;((ViewGroup) w.getDecorView()).addView(view);//view.setBackgroundColor(context.getResources().getColor(R.color.colorPrimaryTaskBar));view.setBackgroundColor(color);}}/*** 计算状态栏颜色** @param color color值* @param alpha alpha值* @return 最终的状态栏颜色*/private static int calculateStatusColor(@ColorInt int color, int alpha) {if (alpha == 0) {return color;}float a = 1 - alpha / 255f;int red = color >> 16 & 0xff;int green = color >> 8 & 0xff;int blue = color & 0xff;red = (int) (red * a + 0.5);green = (int) (green * a + 0.5);blue = (int) (blue * a + 0.5);return 0xff << 24 | red << 16 | green << 8 | blue;}/**** Android设置背景图延伸到状态栏* https://www.codenong.com/cs106491245/* @param context*/public static void transparentStatusBarForImage(Activity context) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//5.0 全透明实现//getWindow.setStatusBarColor(Color.TRANSPARENT)Window window = context.getWindow();window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);window.setStatusBarColor(Color.TRANSPARENT);} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {//4.4 全透明状态栏context.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);}}// 设置状态栏文字颜色为黑色public static void setStatusBarLightMode(Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {View decorView = activity.getWindow().getDecorView();int systemUiVisibility = decorView.getSystemUiVisibility();decorView.setSystemUiVisibility(systemUiVisibility | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);}}// 设置状态栏文字颜色为白色public static void setStatusBarDarkMode(Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {View decorView = activity.getWindow().getDecorView();int systemUiVisibility = decorView.getSystemUiVisibility();decorView.setSystemUiVisibility(systemUiVisibility & ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);}}// 设置状态栏(纯)颜色public static void setStatusBarColor(Activity activity, int colorResId) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {Window window = activity.getWindow();window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);window.setStatusBarColor(activity.getResources().getColor(colorResId));}}public static void setStatusBarColor(Dialog dialog, int colorResId) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {Window window = dialog.getWindow();window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);window.setStatusBarColor(dialog.getContext().getResources().getColor(colorResId));}}/**** 设置dialog的状态栏的字体颜色* @param dialog DialogFragment*/public static void setStatusBarLightMode(Dialog dialog) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {View decorView = dialog.getWindow().getDecorView();int systemUiVisibility = decorView.getSystemUiVisibility();decorView.setSystemUiVisibility(systemUiVisibility | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);}}
}

1.2 AndroidManifest.xml

<!--适配华为(huawei)刘海屏-->
<meta-dataandroid:name="android.notch_support"android:value="true" />
<!--适配小米(xiaomi)刘海屏-->
<meta-dataandroid:name="notch.config"android:value="portrait|landscape" />
<!--   适配全面屏     -->
<meta-dataandroid:name="android.max_aspect"android:value="2.4" />

1.3 ids.xml

<?xml version="1.0" encoding="utf-8"?>
<resources><item type="id" name="statusbarutil_fake_status_bar_view" /><item type="id" name="statusbarutil_translucent_view" />
</resources>

2.NotchScreenTool第三方库

2.1 代码

// 支持显示到刘海区域
NotchScreenManager.getInstance().setDisplayInNotch(this);
// 获取刘海屏信息
NotchScreenManager.getInstance().getNotchInfo(this, new INotchScreen.NotchScreenCallback() {@Overridepublic void onResult(INotchScreen.NotchScreenInfo notchScreenInfo) {Log.i(TAG, "Is this screen notch? " + notchScreenInfo.hasNotch);if (notchScreenInfo.hasNotch) {for (Rect rect : notchScreenInfo.notchRects) {Log.i(TAG, "notch screen Rect =  " + rect.toShortString());}}}
});

2.2 AndroidManifest.xml

<application> 标签中增加属性:android:resizeableActivity="false" 或者不设置

同时在节点下增加一个meta-data标签:

 <!-- Render on full screen up to screen aspect ratio of 2.4 --><!-- Use a letterbox on screens larger than 2.4 --><meta-data android:name="android.max_aspect" android:value="2.4" />

2.3 githup

githup

3.ImmersionBar第三方库

3.1 依赖

// 基础依赖包,必须要依赖
implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2'
// kotlin扩展(可选)
implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.2'
// fragment快速实现(可选)已废弃
implementation 'com.geyifeng.immersionbar:immersionbar-components:3.2.2'

3.2 关于全面屏与刘海

关于全面屏

在manifest加入如下配置,四选其一,或者都写

① 升级targetSdkVersion为25以上版本,现在基本都是25以上了,所以以下三个没有必要配置了

② 在manifest的Application节点中加入

   android:resizeableActivity="true"

③ 在manifest的Application节点中加入

   android:maxAspectRatio="2.4"

④ 在manifest的Application节点下加入

   <meta-data android:name="android.max_aspect"android:value="2.4" />
关于刘海屏

在manifest的Application节点下加入,vivo和oppo没有找到相关配置信息

   <!--适配华为(huawei)刘海屏--><meta-data android:name="android.notch_support" android:value="true"/><!--适配小米(xiaomi)刘海屏--><meta-dataandroid:name="notch.config"android:value="portrait|landscape" />

3.3 Api详解

  • 基础用法

    ImmersionBar.with(this).init();
    
  • 高级用法(每个参数的意义)

     ImmersionBar.with(this).transparentStatusBar()  //透明状态栏,不写默认透明色.transparentNavigationBar()  //透明导航栏,不写默认黑色(设置此方法,fullScreen()方法自动为true).transparentBar()             //透明状态栏和导航栏,不写默认状态栏为透明色,导航栏为黑色(设置此方法,fullScreen()方法自动为true).statusBarColor(R.color.colorPrimary)     //状态栏颜色,不写默认透明色.navigationBarColor(R.color.colorPrimary) //导航栏颜色,不写默认黑色.barColor(R.color.colorPrimary)  //同时自定义状态栏和导航栏颜色,不写默认状态栏为透明色,导航栏为黑色.statusBarAlpha(0.3f)  //状态栏透明度,不写默认0.0f.navigationBarAlpha(0.4f)  //导航栏透明度,不写默认0.0F.barAlpha(0.3f)  //状态栏和导航栏透明度,不写默认0.0f.statusBarDarkFont(true)   //状态栏字体是深色,不写默认为亮色.navigationBarDarkIcon(true) //导航栏图标是深色,不写默认为亮色.autoDarkModeEnable(true) //自动状态栏字体和导航栏图标变色,必须指定状态栏颜色和导航栏颜色才可以自动变色哦.autoStatusBarDarkModeEnable(true,0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦.autoNavigationBarDarkModeEnable(true,0.2f) //自动导航栏图标变色,必须指定导航栏颜色才可以自动变色哦.flymeOSStatusBarFontColor(R.color.btn3)  //修改flyme OS状态栏字体颜色.fullScreen(true)      //有导航栏的情况下,activity全屏显示,也就是activity最下面被导航栏覆盖,不写默认非全屏.hideBar(BarHide.FLAG_HIDE_BAR)  //隐藏状态栏或导航栏或两者,不写默认不隐藏.addViewSupportTransformColor(toolbar)  //设置支持view变色,可以添加多个view,不指定颜色,默认和状态栏同色,还有两个重载方法.titleBar(view)    //解决状态栏和布局重叠问题,任选其一.titleBarMarginTop(view)     //解决状态栏和布局重叠问题,任选其一.statusBarView(view)  //解决状态栏和布局重叠问题,任选其一.fitsSystemWindows(true)    //解决状态栏和布局重叠问题,任选其一,默认为false,当为true时一定要指定statusBarColor(),不然状态栏为透明色,还有一些重载方法.supportActionBar(true) //支持ActionBar使用.statusBarColorTransform(R.color.orange)  //状态栏变色后的颜色.navigationBarColorTransform(R.color.orange) //导航栏变色后的颜色.barColorTransform(R.color.orange)  //状态栏和导航栏变色后的颜色.removeSupportView(toolbar)  //移除指定view支持.removeSupportAllView() //移除全部view支持.navigationBarEnable(true)   //是否可以修改导航栏颜色,默认为true.navigationBarWithKitkatEnable(true)  //是否可以修改安卓4.4和emui3.x手机导航栏颜色,默认为true.navigationBarWithEMUI3Enable(true) //是否可以修改emui3.x手机导航栏颜色,默认为true.keyboardEnable(true)  //解决软键盘与底部输入框冲突问题,默认为false,还有一个重载方法,可以指定软键盘mode.keyboardMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)  //单独指定软键盘模式.setOnKeyboardListener(new OnKeyboardListener() {    //软键盘监听回调,keyboardEnable为true才会回调此方法@Overridepublic void onKeyboardChange(boolean isPopup, int keyboardHeight) {LogUtils.e(isPopup);  //isPopup为true,软键盘弹出,为false,软键盘关闭}}).setOnNavigationBarListener(onNavigationBarListener) //导航栏显示隐藏监听,目前只支持华为和小米手机.setOnBarListener(OnBarListener) //第一次调用和横竖屏切换都会触发,可以用来做刘海屏遮挡布局控件的问题.addTag("tag")  //给以上设置的参数打标记.getTag("tag")  //根据tag获得沉浸式参数.reset()  //重置所以沉浸式参数.init();  //必须调用方可应用以上所配置的参数
    
在Activity中实现沉浸式
  • java用法

     ImmersionBar.with(this).init();
    
  • kotlin用法

     immersionBar {statusBarColor(R.color.colorPrimary) navigationBarColor(R.color.colorPrimary)}
    
在Fragment中实现沉浸式
在Fragment使用ImmersionBar
  • 第一种,fragment如果配合viewpager2使用的话,并且使用了Behavior指定了BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT,直接在fragment的onResume里直接实现沉浸式
  • 第二种,当使用show()和hide()来控制Fragment显示隐藏的时候,直接在fragment的onResume与onHiddenChanged(参数hidden为false)方法里实现沉浸式
  • 第三种(废弃),你的Fragment直接继承SimpleImmersionFragment或者ImmersionFragment类,在initImmersionBar方法中实现沉浸式代码,只有当immersionBarEnabled返回为true才可以走initImmersionBar方法哦,不过immersionBarEnabled默认返回已经为true了,如果当前Fragment不想走沉浸式方法,请将immersionBarEnabled设置为false
  • 第四种(废弃),如果你的Fragment不能继承SimpleImmersionFragment或者ImmersionFragment类,请参考SimpleImmersionFragment实现SimpleImmersionOwner接口,或者参考ImmersionFragment实现ImmersionOwner接口
在Activity使用ImmersionBar
  • 第一种,当结合viewpager2使用的时候,请使用viewpager2的registerOnPageChangeCallback的方法监听沉浸式
  • 第二种,当结合viewpager使用的时候,请使用viewpager的addOnPageChangeListener的方法监听沉浸式,参考demo中FragmentThreeActivity这个类
  • 第三种,当使用show()和hide()来控制Fragment显示隐藏的时候,请在tab切换的时候使用ImmersionBar,参考demo中FragmentFourActivity这个类
使用Fragment第三方框架Fragmentation实现沉浸式
  • 参考demo中FragmentFiveActivity和BaseFiveFragment这个类
在Dialog中实现沉浸式,具体实现参考demo
  • ①结合dialogFragment使用,可以参考demo中的BaseDialogFragment这个类

        ImmersionBar.with(this).init();
    
  • ②其他dialog,关闭dialog的时候必须调用销毁方法

        ImmersionBar.with(this, dialog).init();
    

    销毁方法:

    java中

        ImmersionBar.destroy(this, dialog);
    

    kotlin中

        destroyImmersionBar(dialog)
    
在PopupWindow中实现沉浸式,具体实现参考demo

重点是调用以下方法,但是此方法会导致有导航栏的手机底部布局会被导航栏覆盖,还有底部输入框无法根据软键盘弹出而弹出,具体适配请参考demo。

    popupWindow.setClippingEnabled(false);
状态栏与布局顶部重叠解决方案,六种方案根据不同需求任选其一
  • ① 使用dimen自定义状态栏高度,不建议使用,因为设备状态栏高度并不是固定的

    在values-v19/dimens.xml文件下

        <dimen name="status_bar_height">25dp</dimen>
    

    在values/dimens.xml文件下

        <dimen name="status_bar_height">0dp</dimen>
    

    然后在布局界面添加view标签,高度指定为status_bar_height

       <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/darker_gray"android:orientation="vertical"><Viewandroid:layout_width="match_parent"android:layout_height="@dimen/status_bar_height"android:background="@color/colorPrimary" /><android.support.v7.widget.Toolbarandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/colorPrimary"app:title="方法一"app:titleTextColor="@android:color/white" /></LinearLayout>
    
  • ② 使用系统的fitsSystemWindows属性,使用该属性不会导致输入框与软键盘冲突问题,不要再Fragment使用该属性,只适合纯色状态栏

        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:fitsSystemWindows="true"></LinearLayout>
    

    然后使用ImmersionBar时候必须指定状态栏颜色

        ImmersionBar.with(this).statusBarColor(R.color.colorPrimary).init();
    
    • 注意:ImmersionBar一定要在设置完布局以后使用,
  • ③ 使用ImmersionBar的fitsSystemWindows(boolean fits)方法,只适合纯色状态栏

        ImmersionBar.with(this).fitsSystemWindows(true)  //使用该属性,必须指定状态栏颜色.statusBarColor(R.color.colorPrimary).init();
    
  • ④ 使用ImmersionBar的statusBarView(View view)方法,可以用来适配渐变色状态栏、侧滑返回

    在标题栏的上方增加View标签,高度指定为0dp

        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/darker_gray"android:orientation="vertical"><Viewandroid:layout_width="match_parent"android:layout_height="0dp"android:background="@color/colorPrimary" /><android.support.v7.widget.Toolbarandroid:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/colorPrimary"app:title="方法四"app:titleTextColor="@android:color/white" /></LinearLayout>
    

    然后使用ImmersionBar的statusBarView方法,指定view就可以啦

         ImmersionBar.with(this).statusBarView(view).init();//或者//ImmersionBar.setStatusBarView(this,view);
    
  • ⑤ 使用ImmersionBar的titleBar(View view)方法,原理是设置paddingTop,可以用来适配渐变色状态栏、侧滑返回

             ImmersionBar.with(this).titleBar(view) //可以为任意view,如果是自定义xml实现标题栏的话,标题栏根节点不能为RelativeLayout或者ConstraintLayout,以及其子类.init();//或者//ImmersionBar.setTitleBar(this, view);
    
  • ⑥ 使用ImmersionBar的titleBarMarginTop(View view)方法,原理是设置marginTop,只适合纯色状态栏

             ImmersionBar.with(this).titleBarMarginTop(view)  //可以为任意view.statusBarColor(R.color.colorPrimary)  //指定状态栏颜色,根据情况是否设置.init();//或者使用静态方法设置//ImmersionBar.setTitleBarMarginTop(this,view);
    
解决EditText和软键盘的问题
  • 第一种方案

        ImmersionBar.with(this).keyboardEnable(true)  //解决软键盘与底部输入框冲突问题//  .keyboardEnable(true, WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE//                        | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)  //软键盘自动弹出.init();
    
  • 第二种方案 不使用keyboardEnable方法,只需要在布局的根节点(最外层节点)加上android:fitsSystemWindows="true"属性即可,只适合纯色状态栏

当白色背景状态栏遇到不能改变状态栏字体为深色的设备时,解决方案
      ImmersionBar.with(this).statusBarDarkFont(true, 0.2f) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度.init();
状态栏和导航栏其它方法
  • public static boolean hasNavigationBar(Activity activity)

    判断是否存在导航栏

  • public static int getNavigationBarHeight(Activity activity)

    获得导航栏的高度

  • public static int getNavigationBarWidth(Activity activity)

    获得导航栏的宽度

  • public static boolean isNavigationAtBottom(Activity activity)

    判断导航栏是否在底部

  • public static int getStatusBarHeight(Activity activity)

    获得状态栏的高度

  • public static int getActionBarHeight(Activity activity)

    获得ActionBar的高度

  • public static boolean hasNotchScreen(Activity activity)

    是否是刘海屏

  • public static boolean getNotchHeight(Activity activity)

    获得刘海屏高度

  • public static boolean isSupportStatusBarDarkFont()

    判断当前设备支不支持状态栏字体设置为黑色

  • public static boolean isSupportNavigationIconDark()

    判断当前设备支不支持导航栏图标设置为黑色

  • public static void hideStatusBar(Window window)

    隐藏状态栏

4.EdgeUtils

EdgeUtils:安卓沉浸式方案(edge to edge)封装

githup


http://www.ppmy.cn/ops/15117.html

相关文章

GHO文件安装到Vmware的两种姿势

1、使用 Ghost11.5.1.2269 将gho转换为vmdk文件(虚拟机硬盘)&#xff0c;Vmware新建虚拟机自定义配置&#xff0c;然后添加已有的虚拟硬盘文件。 注意ghost的版本&#xff0c;如果你是用Ghost11.5备份的gho文件&#xff0c;再用Ghost12把gho文件转换为vmdk&#xff0c;则vmdk文…

深度学习之视觉特征提取器——VGG系列

VGG 提出论文&#xff1a;1409.1556.pdf (arxiv.org) 引入 距离VGG网络的提出已经约十年&#xff0c;很难想象在深度学习高速发展的今天&#xff0c;一个模型能够历经十年而不衰。虽然如今已经有VGG的大量替代品&#xff0c;但是笔者研究的一些领域仍然有大量工作选择使用VG…

vue2响应式 VS vue3响应式

Vue2响应式 存在问题&#xff1a; 新增属性&#xff0c;删除属性&#xff0c;界面不会更新。 直接通过下标修改数组界面不会自动更新。 Vue2使用object.defineProperty来劫持数据是否发生改变&#xff0c;如下&#xff1a; 能监测到获取和修改属性&#xff1a; 新增的属性…

服务器数据恢复—存储硬盘坏道,指示灯亮黄色的数据恢复案例

服务器数据恢复环境&故障&#xff1a; 一台某品牌EqualLogic PS系列某型号存储&#xff0c;存储中有一组由16块SAS硬盘组建的RAID5磁盘阵列&#xff0c;RAID5上划分VMFS文件系统存放虚拟机文件。存储系统上层一共分了4个卷。 raid5阵列中磁盘出现故障&#xff0c;有2块硬盘…

安全评估报告 项目安全风险评估报告 信息安全评估报告

一、安全评估报告的意义 安全评估报告是对特定环境、设施或系统安全性进行全 面分析、评估和预测的重要工具。它通过对潜在风险的识别、分析和评价&#xff0c;帮助决策者了解当前安全形势&#xff0c;制定科学的安全策略&#xff0c;从而有 效预防和减少安全事故的发生。安全…

Hive安装与配置实战指南

Hive安装与配置实战指南 在大数据领域中&#xff0c;Hive以其类SQL的查询语言HQL、可扩展的数据仓库能力和对Hadoop生态系统的良好集成&#xff0c;成为了数据分析和处理的重要工具。本文将指导您完成Hive的安装与配置&#xff0c;帮助您快速搭建起自己的Hive环境。 一、环境…

C++静态变量

C语言中与“静态”相关的词包括&#xff0c;静态全局变量&#xff0c;静态局部变量和静态函数&#xff0c;关键词是static。C语言中的变量从作用域分&#xff0c;可以分为全局变量和局部变量&#xff1b;从存储方式分&#xff0c;可以分为静态存储方式和动态存储方式。 1. 静态…

C语言工程调用C++库解决方案

本文为C语言工程调用C库的解决方案。 应用场景&#xff1a; 需要C程序编译成的库提供函数接口&#xff0c;来解决C语言工程的需求。 人的出场顺序真的很重要&#xff0c;很多人如果换一个时间认识&#xff0c;换一个时间共处&#xff0c;一切都将是不一样的场景&#xff0c;不…

鸿蒙原生应用元服务-访问控制(权限)开发应用权限列表二

ohos.permission.ACCELEROMETER 允许应用读取加速度传感器的数据。 权限级别 &#xff1a;normal 授权方式 &#xff1a;system_grant ACL使能 &#xff1a;TRUE ohos.permission.GYROSCOPE 允许应用读取陀螺仪传感器的数据。 权限级别 &#xff1a;normal 授权方式 &a…

C++高级特性:异常概念与处理机制(十四)

1、异常的基本概念 异常&#xff1a;是指在程序运行的过程中发生的一些异常事件&#xff08;如&#xff1a;除数为0&#xff0c;数组下标越界&#xff0c;栈溢出&#xff0c;访问非法内存等&#xff09; C的异常机制相比C语言的异常处理&#xff1a; 函数的返回值可以忽略&…

Mongodb支持事务吗?

一、概念 1.1、MongoDB事务简介 MongoDB 是一个非关系型数据库管理系统&#xff0c;最初并不支持事务。然而&#xff0c;随着时间的推移&#xff0c;MongoDB 在其4.0版本中引入了多文档事务支持&#xff0c;使得在单个集合中执行多个操作成为可能。 In MongoDB, an operation…

C#面:阐述什么是泛型,泛型的优点有哪些?

泛型是 C# 中的一种特性&#xff0c;它允许我们编写可以在不同类型上工作的可重用代码。 通过使用泛型&#xff0c;我们可以编写更加灵活和通用的代码&#xff0c;而不需要为每种类型都编写重复的代码。 泛型的优点有以下几个方面&#xff1a; 代码重用&#xff1a;使用泛型可…

装饰器模式

一、实现原理 装饰器设计模式&#xff08;Decorator&#xff09;是一种结构型设计模式&#xff0c;它允许动态地为对象添加新的行为。它通过创建一个包装器来实现&#xff0c;即将对象放入一个装饰器类中&#xff0c;再将装饰器类放入另一个装饰器类中&#xff0c;以此类推&am…

nginx反向代理

简介 Nginx反向代理是一种服务器架构模式&#xff0c;它允许Nginx服务器接收客户端的请求&#xff0c;然后将这些请求转发到上游服务器&#xff08;例如应用服务器&#xff09;进行处理&#xff0c;并将处理后的响应返回给客户端。在这个过程中&#xff0c;Nginx充当了客户端和…

如何提交已暂存的更改到本地仓库?

文章目录 如何提交已暂存的更改到本地Git仓库&#xff1f;步骤1&#xff1a;确认并暂存更改步骤2&#xff1a;提交暂存的更改到本地仓库 如何提交已暂存的更改到本地Git仓库&#xff1f; 在Git版本控制系统中&#xff0c;当你对项目文件进行修改后&#xff0c;首先需要将这些更…

前端开发攻略---用原生JS在网页中也能实现 文本转语音!

1、原理 语音合成 (也被称作是文本转为语音&#xff0c;英语简写是 tts) 包括接收 app 中需要语音合成的文本&#xff0c;再在设备麦克风播放出来这两个过程。 Web API中对此有一个主要控制接口 SpeechSynthesis&#xff0c;外加一些处理如何表示要被合成的文本 (也被称为 utte…

(避雷指引:管理页面超时问题)windows下载安装RabbitMQ

一、背景&#xff1a; 学习RabbitMQ过程中&#xff0c;由于个人电脑性能问题&#xff0c;直接装在windows去使用RabbitMQ&#xff0c;根据各大网友教程&#xff0c;去下载安装完之后&#xff0c;使用web端进行简单的入门操作时&#xff0c;总是一直提示超时&#xff0c;要么容…

2024年华为OD机试真题-考勤信息-Python-OD统一考试(C卷D卷)

题目描述: 公司用一个字符串来表示员工的出勤信息: absent:缺勤 late:迟到 leaveearly:早退 present:正常上班 现需根据员工出勤信息,判断本次是否能获得出勤奖,能获得出勤奖的条件如下: 缺勤不超过一次;没有连续的迟到/早退;任意连续7次考勤,缺勤/迟到/早退不超过…

GaussDB轻量化运维管理工具介绍

前言 本期课程将从管理平台的架构出发&#xff0c;结合平台的实例管理、实例升级、容灾管理和监控告警的功能和操作介绍&#xff0c;全面覆盖日常运维操作&#xff0c;带您理解并熟练运用GaussDB运维平台完成运维工作。 一、GaussDB 运维管理平台简介 开放生态层 友好Web界面…

Python 基于docker部署的Mysql备份查询脚本

前言 此环境是基于docker部署的mysql&#xff0c;docker部署mysql可以参考如下链接&#xff1a; docker 部署服务案例-CSDN博客 颜色块文件 rootbogon:~ 2024-04-18 16:34:23# cat DefaultColor.py ######################################################################…