Android 屏幕适配全攻略(下)-百变屏幕无压力,这才是Android屏幕适配的终极解决方案


在上一篇文章中,我们介绍了Android屏幕适配的基本方法,比如使用限定符资源、图片适配、矢量图等。

感兴趣的朋友,请前往查阅:Android 屏幕适配全攻略(中)-从九宫格到矢量图,揭秘Android多屏幕适配的正确打开方式.


但随着智能手机屏幕形态的不断创新,光靠这些基础做法已经不够,开发者们必须进一步掌握更多专业的适配技巧,才能应对屏幕百变的挑战。本文将重点讲解字体缩放适配、Android 9.0新屏幕支持、异形全面屏等内容,为您分享Android屏幕适配的终极解决之道。


一、字体缩放适配


Android系统为了给用户带来极佳的可访问性体验,允许他们自由调节系统字体大小。所以作为开发者,我们必须确保应用可以完美兼容各种字体缩放场景,既能满足用户需求,也不会破坏界面布局。


1、代码中动态计算、设置字体大小以适应不同的屏幕密度和尺寸


public class MainActivity extends AppCompatActivity {private static final float BASE_FONT_SIZE = 16f; // 基准字体大小,单位 SPprivate static final float BASE_SCREEN_WIDTH = 360f; // 基准屏幕宽度,单位 DP@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 获取屏幕宽度int screenWidth = getScreenWidth(this);// 计算动态字体大小float dynamicFontSize = calculateDynamicFontSize(screenWidth);// 设置 TextView 的字体大小TextView textView = findViewById(R.id.text_view);textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, dynamicFontSize);}/*** 获取屏幕宽度(单位:DP)*/private static int getScreenWidth(Context context) {DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();return (int) (displayMetrics.widthPixels / displayMetrics.density);}/*** 计算动态字体大小(单位:SP)*/private static float calculateDynamicFontSize(float screenWidth) {return BASE_FONT_SIZE * (screenWidth / BASE_SCREEN_WIDTH);}
}

在这个示例中:

  • 我们定义了基准字体大小 BASE_FONT_SIZE 为 16sp,以及基准屏幕宽度 BASE_SCREEN_WIDTH 为 360dp。
  • onCreate 方法中,我们先获取当前屏幕的宽度(单位为 dp),然后调用 calculateDynamicFontSize 方法计算出动态的字体大小(单位为 sp)。
  • 最后,我们将计算出的动态字体大小设置到 TextView 上。

calculateDynamicFontSize 方法的实现原理如下:

  • 我们假设基准字体大小 16sp 对应了基准屏幕宽度 360dp。
  • 当屏幕宽度发生变化时,我们可以按照屏幕宽度的比例来计算出新的字体大小。
  • 具体计算公式为: dynamicFontSize = BASE_FONT_SIZE * (screenWidth / BASE_SCREEN_WIDTH),其中 screenWidth 为当前屏幕的宽度(单位为 dp)。

通过这种方式,我们可以自动根据屏幕尺寸动态调整字体大小,从而确保文字在不同设备上的显示效果都能较为合理。


2、代码中对文字进行缩放


主要涉及到以下几个方面:

  • 使用 sp 作为字体单位 Android 建议使用 sp (scale-independent pixels) 作为字体的单位,因为 sp 会根据用户的字体大小设置进行缩放,能够确保文字大小在不同设备上显示合理。

  • 继承 Application 类并重写 attachBaseContext 方法 在应用启动时,可以在自定义的 Application 类中重写 attachBaseContext 方法,在这里对整个应用的字体大小进行缩放适配。

  • 使用 TextUtil 工具类 Android 提供了 TextUtil 工具类,可以对文字内容进行缩放。在需要缩放的地方,调用 TextUtil.scale(CharSequence source, float proportion) 方法即可。


下面是一个完整的 Java 代码示例:

public class MyApplication extends Application {private static final float DEFAULT_FONT_SCALE = 1.0f;@Overrideprotected void attachBaseContext(Context base) {super.attachBaseContext(base);// 获取当前系统的字体缩放比例float fontScale = base.getResources().getConfiguration().fontScale;// 计算需要缩放的比例float scale = fontScale / DEFAULT_FONT_SCALE;// 对整个应用的字体进行缩放ResourcesCompat.getFont(base).setCompatibilityScaling(scale);}
}public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView textView = findViewById(R.id.text_view);// 对单个 TextView 的文字进行缩放textView.setText(TextUtils.scale(textView.getText(), 1.2f));}
}

在这个示例中:

  • 自定义的 MyApplication 类重写了 attachBaseContext 方法,获取当前系统的字体缩放比例,并对整个应用的字体进行缩放适配。

  • MainActivity 中,我们使用 TextUtils.scale() 方法对单个 TextView 的文字进行了 1.2 倍的缩放。


3、设置布局根元素的autoSizeTextType属性

<LinearLayout...app:autoSizeTextType="uniform"><TextViewandroid:textSize="16sp"... /></LinearLayout>

autoSizeTextType可以让布局内所有文字自动调整大小以完全适应布局高宽。


二、Android 9.0 带来的全新屏幕支持


1、支持异形全面屏

Android 9.0(Pie)正式推出后,Google 在屏幕显示方面做了全面的升级,其中最重要的就是对异形全面屏的支持。

异形全面屏指的是屏幕四周有凹槽或者凸起的屏幕设计,常见于 iPhone X、三星 Galaxy S9 等手机。Android 9.0 提供了一系列 API 和特性来支持这种屏幕形态,包括:

  • DisplayCutout API: 这个 API 可以让开发者获取到屏幕上的"凹槽"区域的信息,包括位置、尺寸等,从而可以更好地适配应用界面。

  • Window Insets: Android 9.0 还提供了 Window Insets 机制,可以让开发者知道当前窗口被系统 UI 遮挡的区域,从而调整界面布局。

  • notch-friendly 导航栏: Android 9.0 的导航栏可以自动适应异形屏幕,当有凹槽时会自动避开。


(1)、使用 DisplayCutout API 适配异形全面屏示例

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 获取 Window 的 DecorViewfinal View decorView = getWindow().getDecorView();// 设置 OnApplyWindowInsets 监听器decorView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {@Overridepublic WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {// 获取屏幕四周的"凹槽"区域DisplayCutout displayCutout = insets.getDisplayCutout();if (displayCutout != null) {// 获取"凹槽"的位置和尺寸Rect safeInsets = displayCutout.getSafeInsetLeft(),safeInsets = displayCutout.getSafeInsetTop(),safeInsets = displayCutout.getSafeInsetRight(),safeInsets = displayCutout.getSafeInsetBottom();// 根据"凹槽"信息调整界面布局adjustLayoutForCutout(decorView, safeInsets);}// 返回 insets 信息,以便系统继续处理return insets;}});}private void adjustLayoutForCutout(View view, Rect safeInsets) {// 根据"凹槽"信息调整 view 的内边距view.setPadding(safeInsets.left, safeInsets.top,safeInsets.right, safeInsets.bottom);// 如果 view 是 ViewGroup,则递归调整子 viewif (view instanceof ViewGroup) {ViewGroup viewGroup = (ViewGroup) view;for (int i = 0; i < viewGroup.getChildCount(); i++) {adjustLayoutForCutout(viewGroup.getChildAt(i), safeInsets);}}}
}

在这个示例中:

  • 我们为 WindowDecorView 设置了 OnApplyWindowInsetsListener 监听器,在这个监听器中获取屏幕"凹槽"的信息。
  • 我们通过 DisplayCutout 获取到"凹槽"的位置和尺寸(用 Rect 表示),并将这些信息传递给 adjustLayoutForCutout 方法。
  • adjustLayoutForCutout方法会遍历DecorView及其所有子View`,并根据"凹槽"信息调整它们的内边距,从而避免内容被"凹槽"遮挡。

通过这种方式,我们可以确保应用的界面能够完美适配异形全面屏,不会出现内容被"凹槽"遮挡的问题。


(2)、使用 Window Insets 适配异形全面屏的示例

public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 获取 Window 的 DecorViewfinal View decorView = getWindow().getDecorView();// 设置 OnApplyWindowInsets 监听器decorView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {@Overridepublic WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {// 获取系统 UI 遮挡的区域Rect systemWindowInsets = new Rect(insets.getSystemWindowInsetLeft(),insets.getSystemWindowInsetTop(),insets.getSystemWindowInsetRight(),insets.getSystemWindowInsetBottom());// 获取"安全区域"(即不被遮挡的区域)Rect displayCutoutSafeInsets = insets.getDisplayCutout() != null? insets.getDisplayCutout().getSafeInsets(): new Rect();// 打印调试信息Log.d(TAG, "System UI insets: " + systemWindowInsets);Log.d(TAG, "Display cutout safe insets: " + displayCutoutSafeInsets);// 根据 insets 信息调整界面布局adjustLayoutForInsets(decorView, systemWindowInsets, displayCutoutSafeInsets);// 返回 insets 信息,以便系统继续处理return insets;}});}private void adjustLayoutForInsets(View view, Rect systemWindowInsets, Rect displayCutoutSafeInsets) {// 根据系统 UI 遮挡区域调整 view 的内边距view.setPadding(systemWindowInsets.left + displayCutoutSafeInsets.left,systemWindowInsets.top + displayCutoutSafeInsets.top,systemWindowInsets.right + displayCutoutSafeInsets.right,systemWindowInsets.bottom + displayCutoutSafeInsets.bottom);// 如果 view 是 ViewGroup,则递归调整子 viewif (view instanceof ViewGroup) {ViewGroup viewGroup = (ViewGroup) view;for (int i = 0; i < viewGroup.getChildCount(); i++) {adjustLayoutForInsets(viewGroup.getChildAt(i), systemWindowInsets, displayCutoutSafeInsets);}}}
}

在这个示例中:

  • 我们为 WindowDecorView 设置了 OnApplyWindowInsetsListener 监听器,在这个监听器中获取系统 UI 遮挡的区域以及"安全区域"(即不被遮挡的区域)。

  • 我们通过 WindowInsets 对象的 getSystemWindowInsetXXX() 方法获取系统 UI 遮挡的区域,并通过 getDisplayCutout().getSafeInsets() 方法获取"安全区域"。

  • 我们将这两个区域信息传递给 adjustLayoutForInsets 方法,该方法会遍历 DecorView 及其所有子 View,并根据遮挡区域信息调整它们的内边距,从而避免内容被遮挡。

通过这种方式,我们可以确保应用的界面能够完美适配异形全面屏,不会出现内容被系统 UI 遮挡的问题。


(3)、notch-friendly 导航栏适配异形全面屏的示例


Android 9.0 (Pie) 引入了"notch-friendly"的导航栏,可以自动适应异形全面屏。开发者可以通过设置 WindowManager.LayoutParams 来让应用的导航栏自动适配屏幕"凹槽"(Notch)。

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 获取 Window 的 LayoutParamsWindowManager.LayoutParams layoutParams = getWindow().getAttributes();// 设置 layoutParams 为 FLAG_LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES// 这样可以让导航栏自动适应屏幕"凹槽"layoutParams.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;getWindow().setAttributes(layoutParams);}
}

在这个示例中,我们主要做了以下几个步骤:

  • 获取当前 WindowLayoutParams
  • layoutInDisplayCutoutMode 属性设置为 LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES。这个值表示应用的导航栏会自动适应屏幕"凹槽",避免内容被遮挡。
  • 将修改后的 LayoutParams 应用到 Window 上。

通过这种方式,我们可以确保应用的导航栏能够自动适应异形全面屏,不会出现内容被"凹槽"遮挡的问题。


值得注意的是,除了设置 layoutInDisplayCutoutMode 属性,Android 9.0 还提供了其他几种适配模式,开发者可以根据自己的需求进行选择:

  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT: 默认模式,系统会自动适配"凹槽"。
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER: 永远不会让内容进入"凹槽"区域。
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES: 适配"凹槽",但只会在屏幕短边(顶部或底部) 出现"凹槽"时生效。
  • LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS: 总是让内容进入"凹槽"区域。

根据具体需求选择合适的模式,可以让应用的界面更好地适配异形全面屏。


三、Android 10 支持可折叠设备多窗口模式


Android 10 及以上版本引入了对可折叠设备的多窗口模式支持。开发者可以利用这些特性来为用户提供更好的体验。

下面代码实现可折叠设备多窗口模式适配的示例:

public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 获取 Window 的 DecorViewfinal View decorView = getWindow().getDecorView();// 设置 OnApplyWindowInsets 监听器decorView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {@Overridepublic WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {// 获取窗口模式信息int windowingMode = insets.getWindowingMode();// 根据窗口模式调整界面布局adjustLayoutForWindowingMode(decorView, windowingMode);// 返回 insets 信息,以便系统继续处理return insets;}});}private void adjustLayoutForWindowingMode(View view, int windowingMode) {switch (windowingMode) {case WINDOWING_MODE_MULTI_WINDOW:// 多窗口模式下的布局调整handleMultiWindowMode(view);break;case WINDOWING_MODE_FREEFORM:// 自由模式下的布局调整handleFreeformMode(view);break;default:// 全屏模式下的布局调整handleFullscreenMode(view);break;}// 如果 view 是 ViewGroup,则递归调整子 viewif (view instanceof ViewGroup) {ViewGroup viewGroup = (ViewGroup) view;for (int i = 0; i < viewGroup.getChildCount(); i++) {adjustLayoutForWindowingMode(viewGroup.getChildAt(i), windowingMode);}}}private void handleMultiWindowMode(View view) {// 多窗口模式下的布局调整逻辑,例如:// - 调整字体大小// - 调整控件尺寸// - 调整控件间距// - ...}private void handleFreeformMode(View view) {// 自由模式下的布局调整逻辑,例如:// - 调整字体大小// - 调整控件尺寸// - 调整控件间距// - ...}private void handleFullscreenMode(View view) {// 全屏模式下的布局调整逻辑,例如:// - 恢复字体大小// - 恢复控件尺寸// - 恢复控件间距// - ...}
}

在这个示例中:

  • 我们为 WindowDecorView 设置了 OnApplyWindowInsetsListener 监听器,在这个监听器中获取当前的窗口模式。
  • 我们通过 WindowInsets 对象的 getWindowingMode() 方法获取当前的窗口模式,并将其传递给 adjustLayoutForWindowingMode 方法。
  • adjustLayoutForWindowingMode 方法会根据当前的窗口模式(多窗口、自由模式或全屏模式)调用相应的处理方法(handleMultiWindowModehandleFreeformModehandleFullscreenMode)。
  • 在这些处理方法中,我们可以根据不同的窗口模式调整界面布局,例如调整字体大小、控件尺寸、控件间距等。

通过这种方式,我们可以确保应用的界面能够在不同的窗口模式下都能提供良好的用户体验。

需要注意的是,不同的可折叠设备可能会有不同的窗口模式支持,开发者需要根据具体的设备和场景进行适配和调整。同时,可以利用 Android Studio 的设备模拟器来进行测试和调试。


四、屏幕适配的最佳实践

除了上述重点内容,我们还需要注意以下一些屏幕适配的最佳实践:

  • 尽量使用约束布局ConstraintLayout,减少嵌套层级

  • 适度使用硬编码数值,避免滥用资源文件

  • 谨慎使用绝对坐标,注意横竖屏切换情况

  • 减少对wrap_content的过度使用

  • 使用tools命名空间标签模拟数据,方便预览调整

  • 持续关注Android新特性,跟上屏幕创新步伐


结语:

随着可折叠手机、环形屏等新形态的出现,Android屏幕适配面临的挑战也将与日俱增。作为开发者,我们需要不断学习创新,跟上屏幕革新的步伐,才能为用户呈现无与伦比的体验。对于Android未来的屏幕支持,你有什么期待?让我们拭目以待,共同努力打造最佳的屏幕适配实践!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/10446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

模拟集成电路(3)----单级放大器(共源极)

模拟集成电路(3)----单级放大器&#xff08;共源极&#xff09; 放大是模拟电路的基本功能 大多数自然模拟信号太小而无法处理需要足够的信噪比 理想的放大器 线性&#xff1a;无限的幅度和频率范围 输入阻抗无限大 输出阻抗无限小 共源放大器 共源放大器就是将源极接A…

01面向类的讲解

指针指向类成员使用 代码&#xff1a; #include<iostream> using namespace std;class Test { public:void func() { cout << "call Test::func" << endl; }static void static_func();int ma;static int mb; //不依赖对象 }; void Test::static…

JavaScript 动态网页实例 —— 事件处理应用

前言 事件处理的应用很广泛。在事件处理的应用中,鼠标事件的应用是最常用到的。本章给出几个鼠标事件处理应用的示例,包括:页面预览、图像切换、点亮文本、鼠标跟随、鼠标感应和禁用鼠标按键。在这些示例中,有的可以直接拿来应用,有的则只提供了一种应用的方法,稍加拓展,…

示例十一、声音传感器

通过以下几个示例来具体展开学习,了解声音传感器原理及特性&#xff0c;学习声音传感器的应用&#xff08;干货版&#xff09;&#xff1a; 示例十一、声音传感器 ino文件源码&#xff1a; //Arduino C demo void setup() {Serial.begin(9600);pinMode(5, OUTPUT); }void loo…

机器学习-无监督学习

无监督学习是机器学习和人工智能的另一个重要分支&#xff0c;它主要处理没有标签的数据集&#xff0c;目的是发现数据中的隐藏模式、结构或异常。无监督学习不依赖于预先定义的输出&#xff0c;而是让算法自己揭示数据的本质特征。 无监督学习的过程通常包括以下几个步骤&…

标准服务器控件

文本类型控件 通常指的是用于输入或显示文本的控件。 TextBox&#xff1a;这是最基本的文本输入控件。它允许用户在页面上输入文本。你可以设置它的属性来控制其行为&#xff0c;如MaxLength&#xff08;限制输入的最大字符数&#xff09;、ReadOnly&#xff08;是否只读&…

【C/C++笔试练习】DNS设置文件、应用层、Dos攻击、DNS服务、DNS、子网划分、http状态、路由设置、TCP连接、HTTP状态码、剪花布条、客似云来

文章目录 C/C笔试练习选择部分&#xff08;1&#xff09;DNS设置文件&#xff08;2&#xff09;应用层&#xff08;3&#xff09;Dos攻击&#xff08;4&#xff09;DNS服务&#xff08;5&#xff09;DNS&#xff08;6&#xff09;子网划分&#xff08;7&#xff09;http状态&am…

docker01-简介和概述

什么是docker&#xff1f; 我们现在开发项目是在windows操作系统使用idea开发&#xff0c;本地windows操作系统上有我们项目所需的jdk&#xff0c;mysql&#xff0c;redis&#xff0c;tomcat等环境&#xff0c;如果我们想打包我们的项目到一个别的服务器上&#xff0c;在别的服…

【Apache POI】Apache POI-操作Excel表格-简易版

Catalog Apache POI-操作Excel表格1. 需求2. 优点3. 缺点4. 应用场景5. 使用方法6. SpringBoot工程中处理Excel表格7. Demo示例 Apache POI-操作Excel表格 1. 需求 大多数项目的在运营过程中&#xff0c;会产生运营数据&#xff0c;如外卖系统中需要统计每日的订单完成数、每…

SpringBoot实现图片验证码

引入依赖 <dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6.2</version> </dependency>代码实现 package com.qiangesoft.captcha.controller;import com.wf.captcha.*…

最少数量线段覆盖-华为OD

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输入描述三、输出描述四、java代码五、测试用例 前言 本人最近再练习算法&#xff0c;所以会发布一些解题思路&#xff0c;希望大家多指教 一、题目描述 给定坐标轴上的一组线段&#xff0c;线段的起点和终点均为整数…

C++:类与对象—继承

类与对象—继承 一、继承是什么&#xff1f;二、继承定义三、基类和派生类对象赋值转换四、继承中的作用域五、派生类的默认成员函数六、继承与友元七、继承与静态成员八、复杂的菱形继承及菱形虚拟继承九、继承的总结和反思十、考察重点 一、继承是什么&#xff1f; 继承(inh…

知识付费系统需要哪些资质要求,教育机构教务工作计划内容有哪些?

每个培训教育机构都是由很多人员组成&#xff0c;作为教育机构&#xff0c;老师不必须&#xff0c;是必不可少的&#xff0c;但是除了老师之外还得配备一定数量的销售人员和教务工作者&#xff0c;教务老师其实也就是搞后勤的&#xff0c;但是是必须的&#xff0c;那么教育机构…

Java的时间类

1. 日期类 1.1 第一代日期类 1) Date: 精确到毫秒&#xff0c;代表特定的瞬间 2) SimpleDateFormat: 格式和解析日期的类 SimpleDateFormat 格式化和解析日期的具体类。它允许进行格式化(日期-→>文本)、解析(文本->日期)和规范化. import java.text.ParseExce…

Java基础(27)Web应用中web.xml文件中可以配置哪些内容

在Java Web应用中&#xff0c;web.xml文件&#xff08;也被称为部署描述符&#xff09;是一个核心的配置文件&#xff0c;它位于应用的WEB-INF目录下。web.xml文件中可以配置多种不同的组件和参数&#xff0c;它们用来定义和调整应用的行为。以下是一些web.xml中可以配置的内容…

Web3 Tools - 助记词生成(完整代码)

工具介绍 Web3Tools - 助记词生成 完整代码 代码路径 import React, { useState } from react; import Grid from mui/material/Grid; import Paper from mui/material/Paper; import Typography from mui/material/Typography; import Button from mui/material/Button; i…

接口自动化测试很难掌握吗?

一. 什么是接口测试 接口测试是一种软件测试方法&#xff0c;用于验证不同软件组件之间的通信接口是否按预期工作。在接口测试中&#xff0c;测试人员会发送请求并检查接收到的响应&#xff0c;以确保接口在不同场景下都能正常工作。 就工具而言&#xff0c;常见的测试工具有…

AI+招聘:ATS招聘系统让HR简历筛选精准度达95%!

一提起招聘过程&#xff0c;许多HR就会想到那堆叠如山的简历、让人眼花缭乱的招聘网站以及琐碎繁复的手动数据录入。据统计&#xff0c;平均每位HR每年要处理数百甚至上千份简历&#xff0c;耗费大量精力在初级筛选和跟进上。   市场调查机构近日发布的一份报告显示&#xff…

【深度学习】YOLO源码中的mAP计算代码的理解笔记(大部分代码逐行+基础解释)

提示&#xff1a;本篇博客是在阅读了YOLO源码中的mAP计算方法的代码后加上官方解释以及自己的debug调试理解每一步是怎么操作的。由于是大部分代码进行了逐行解释&#xff0c;所以篇幅过长。 文章目录 前言一、输入格式处理1.1 转换公式二、init&#xff1a;初始化2.1 iouv2.2 …

AND Sorting题解

AND Sorting题解 AND Sorting 详细 题解()题目原意解题思路这是代码🐬ZZZB. AND Sorting(我也是有底线的)AND Sorting 详细 题解() 洛谷 原题,CF 原题 洛谷 AC记录,CF AC记录 题目原意 给你一个由从 0 0 0 到 n − 1 n-1 n−1 的整数组成的排列 p p p (每个整数都…