当前位置: 首页 > news >正文

Android Edge-to-Edge

Android Edge-to-Edge显示:开发者综合指南

一、什么是Android Edge-to-Edge

​ Android Edge-to-Edge是一种先进的用户界面(UI)设计理念,旨在最大化利用设备的显示区域。它允许应用程序的内容延伸至屏幕的各个边缘,包括传统上由系统UI元素(如状态栏、导航栏和标题栏)占据的区域,以及物理显示切口(例如摄像头刘海屏或打孔屏)的下方 。通过将UI绘制在这些通常保留给系统界面的区域下方,Edge-to-Edge设计为用户提供了更具沉浸感的全屏视觉体验 。这种方法消除了屏幕边缘常见的黑边或空白区域,使得应用程序的视觉呈现更加现代和无缝 。
Android平台从Android 15 (API 35) 开始,对于目标SDK为35或更高版本的应用程序,Edge-to-Edge行为将自动启用并强制执行 。这意味着,如果应用程序未能主动适应这种变化,其部分UI元素可能会被系统UI遮挡,从而严重影响用户体验和应用程序的功能性 。这种平台行为的转变并非偶然,而是Google致力于标准化和推广现代、沉浸式UI体验的明确信号。随着Android 16 (API 36) 进一步移除Edge-to-Edge行为的临时Opt-Out选项,这种趋势变得更加不可逆转 。这预示着Edge-to-Edge不仅仅是一个可选的新功能,更是Android应用程序UI管理方式的根本性转变,要求开发者必须积极地进行适应和调整。
最后,随着Edge-to-Edge设计的普遍采用和强制执行,用户对应用程序UI的期望值也随之提高。当大多数应用程序都能够提供全屏沉浸式体验时,那些未能充分利用全屏空间、仍然显示传统黑边或不透明系统栏的应用程序,可能会被用户视为过时或设计不佳。这种感知上的差异可能导致应用程序在用户体验和市场竞争力方面处于劣势,因此,开发者有必要积极拥抱Edge-to-Edge,以满足不断变化的用户期望并保持应用程序的竞争力。
系统栏和显示切口
在Android设备上,系统栏是操作系统提供的关键UI区域,它们承载着重要的系统信息和交互功能 。主要包括:
* 状态栏 (Status Bar): 位于屏幕顶部,显示通知图标、时间、电池电量、信号强度等系统信息 。
* 导航栏 (Navigation Bar): 位于屏幕底部,提供返回、主页、多任务等设备导航控件。导航栏可以是经典的三键式(返回、主页、最近任务),也可以是现代的手势导航栏,通过滑动手势进行操作 。
除了系统栏,现代智能手机还普遍存在显示切口 (Display Cutouts)。这些区域是指设备屏幕上延伸到显示表面的物理区域,通常是为了容纳前置摄像头、传感器或其他硬件组件(例如,刘海屏、水滴屏、打孔屏) 。在Edge-to-Edge模式下,应用程序的内容会绘制到这些区域的后面。因此,开发者必须妥善处理这些显示切口,以确保应用程序的关键UI元素不会被遮挡,同时保持视觉上的连续性和美观性 。

二、理解Window Insets

2.1 Window Insets的类型与作用

 Window Insets是Android系统中一个核心机制,用于描述应用程序内容需要多少内边距(padding)或边距(margin)以避免与系统UI元素或物理设备特性(如显示切口)重叠 。它们代表了屏幕上应用程序可能与系统UI相交的部分,并提供了这些区域的精确尺寸信息 。每个Inset类型都包含四个像素维度:顶部、左侧、右侧和底部,精确地指示了系统UI从屏幕相应边缘延伸的距离 。

以下是主要的Window Insets类型及其作用:

​ 1. WindowInsets.statusBars: 描述状态栏的内边距,即屏幕顶部包含通知和系统图标的区域 。

​ 2. WindowInsets.navigationBars: 描述导航栏的内边距,即屏幕底部或侧面包含导航控件(如返回、主页)的区域 。

​ 3. WindowInsets.captionBar: 描述标题栏的内边距,通常用于自由浮动窗口的顶部标题栏 。

​ 4. WindowInsets.systemBars: 状态栏、导航栏和标题栏的联合内边距,是所有系统UI栏的综合表示 。

​ 5. WindowInsets.displayCutout: 描述显示切口(如刘海、打孔)的内边距,用于避免内容被物理遮挡 。

​ 6. WindowInsets.ime: 描述软件键盘(Input Method Editor, IME)占据的底部空间内边距。这对于处理键盘弹出和隐藏时的UI调整至关重要,确保输入框不被键盘遮挡 。

​ 7. WindowInsets.systemGestures: 描述系统手势(如边缘滑动返回手势、主页手势)可能拦截的区域。使用此Inset类型可以避免应用程序自身的手势(如底部抽屉、轮播图或游戏中的滑动)与系统手势发生冲突 。

为了简化开发,Android还提供了几种“安全”Inset类型,它们是上述基础Inset类型的组合,用于更通用地保护内容:

​ 8. WindowInsets.safeDrawing: 最常用的安全内边距类型,用于保护不应被任何系统UI(包括状态栏、导航栏、显示切口和IME)遮挡的内容。这是防止内容视觉重叠的主要手段 。

​ 9.WindowInsets.safeGestures: 用于保护带有手势的内容,避免与系统手势区域重叠,从而防止手势冲突 。

​ 10. WindowInsets.safeContent: 是 safeDrawing 和 safeGestures 的组合,旨在确保内容既没有视觉重叠,也没有手势重叠,提供最全面的安全区域 。

WindowInsets的细粒度类型(如statusBars、navigationBars、ime、safeDrawing、safeGestures)揭示了有效的Edge-to-Edge实现并非简单的全局填充。应用程序的UI元素具有不同的功能和交互需求。例如,一个可点击的按钮需要完全可见且可触及,而一个背景图像则可以延伸到系统栏下方。因此,开发者需要根据UI元素的具体功能和其在屏幕上的位置,选择并应用最合适的Inset类型,从而精确地避免视觉遮挡和手势冲突。这种方法要求开发者从静态布局调整转向动态、响应式的UI设计,以确保每个组件都能在最佳位置呈现。
WindowInsets对视觉遮挡、手势冲突乃至键盘状态的全面覆盖,体现了Android平台致力于实现真正自适应和响应式UI设计的决心。系统UI元素(如状态栏、导航栏、键盘)在不同设备形态、屏幕尺寸、用户设置(例如三键导航与手势导航的切换)下,其大小和行为可能存在显著差异。通过提供如此详尽的Inset信息,平台不仅鼓励,而且促使开发者采用“为所有屏幕设计”的理念。这意味着应用程序不再依赖固定尺寸或硬编码的边距,而是利用系统提供的工具动态地适应环境变化,确保无论设备如何,功能和可用性都能得到维护,从而提供一致且高质量的用户体验。

2.2 Insets如何解决内容重叠

​ 当应用程序采用Edge-to-Edge布局时,其内容会绘制到系统栏和显示切口下方,这可能导致关键UI元素被遮挡或与系统UI重叠 。Window Insets正是为了解决这些重叠问题而设计的。通过获取相应的Window Insets值,开发者可以动态地调整UI元素的布局、边距或填充,从而确保关键内容和可交互元素不会被系统UI遮挡 。
​ 例如,对于应用程序中可点击的视图(如浮动操作按钮),可以使用系统栏内边距来增加其边距,使其不会被导航栏或状态栏覆盖 。对于有显示切口的设备,开发者需要为受影响的区域添加额外的填充,以避免重要的内容(如文本或图像)被切口遮挡 。此外,对于滚动内容,例如RecyclerView或LazyColumn,可以通过设置clipToPadding="false"并应用内边距,使内容在滚动时能够延伸到系统栏下方,同时确保列表的最后一个元素不会被导航栏遮挡

表:Window Insets类型及其应用场景

Inset Type (英文名称)中文描述典型应用场景
WindowInsets.statusBars状态栏的内边距防止顶部内容(如应用标题、图标)被状态栏遮挡。
WindowInsets.navigationBars导航栏的内边距防止底部内容(如底部导航栏、浮动按钮)被导航栏遮挡。
WindowInsets.captionBar标题栏的内边距主要用于自由浮动窗口,防止内容被窗口装饰(如标题栏)遮挡。
WindowInsets.systemBars状态栏、导航栏和标题栏的联合内边距适用于需要整体避开所有系统UI栏的场景,如根布局的通用填充。
WindowInsets.displayCutout物理显示切口(刘海、打孔)的内边距调整布局以避开屏幕上的物理切口,确保关键UI不被遮挡。
WindowInsets.ime软件键盘(IME)占据的底部空间内边距在键盘弹出时,动态调整输入框或滚动视图的位置,防止内容被键盘遮挡。
WindowInsets.systemGestures系统手势(如边缘滑动返回)可能拦截的区域调整可滑动或可拖动的UI元素位置,避免与系统手势冲突,如底部抽屉、轮播图。
WindowInsets.safeDrawing保护不应被任何系统UI(包括状态栏、导航栏、显示切口和IME)遮挡的内容最常用的安全内边距,用于防止内容被视觉遮挡,适用于大多数可交互元素。
WindowInsets.safeGestures保护带有手势的内容,避免与系统手势冲突适用于需要自定义手势交互的区域,确保应用手势优先。
WindowInsets.safeContentsafeDrawingsafeGestures 的组合提供最全面的安全区域,确保内容既无视觉重叠也无手势重叠。

三、没有做好准备,如何避免被强制Edge-to-Edge

要避免应用程序进入“Edge-to-edge”模式(即避免内容绘制到系统栏后面),通常意味着你希望系统栏(状态栏和导航栏)保持它们传统的可见、不透明或半透明的背景,并且你的应用内容不绘制到这些区域后面。

以下是避免进入 Edge-to-edge 模式的几种方法:

3.1 不调用 enableEdgeToEdge()WindowCompat.setDecorFitsSystemWindows(window, false)

这是最直接的方法。enableEdgeToEdge() 是 Jetpack Activity 库提供的一个便捷函数,它会自动设置窗口标志以实现 Edge-to-edge。如果你不调用它,并且也没有手动设置 WindowCompat.setDecorFitsSystemWindows(window, false),那么你的应用默认就不会进入完全的 Edge-to-edge 模式。

在 Views 系统中,WindowCompat.setDecorFitsSystemWindows(window, false) 的作用是告诉窗口视图内容可以绘制到系统窗口装饰(包括系统栏)后面。如果设置为 true(默认值),则系统会自动为内容添加填充,使其避免与系统栏重叠。

示例 (Kotlin):

Kotlin

class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 不要调用 enableEdgeToEdge()// 或者确保 WindowCompat.setDecorFitsSystemWindows(window, true) 是默认或显式设置的// WindowCompat.setDecorFitsSystemWindows(window, true) // 这通常是默认行为setContentView(R.layout.activity_main)// ...}
}

3.2 在主题中设置 android:windowTranslucentStatusandroid:windowTranslucentNavigationfalse (旧方法,不推荐用于最新 Android 版本)

在旧版本的 Android 中,这些属性可以控制状态栏和导航栏的半透明性。将它们设置为 false 可以避免它们变透明。然而,在较新的 Android 版本中,尤其是在 Android 15 及更高版本中,这种方法可能不再有效,因为系统可能会强制执行 Edge-to-edge。

示例 (themes.xml):

XML

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"><item name="android:windowTranslucentStatus">false</item><item name="android:windowTranslucentNavigation">false</item><item name="android:statusBarColor">@android:color/transparent</item><item name="android:navigationBarColor">@android:color/transparent</item>
</style>
```

3.3 在主题中设置 android:windowOptOutEdgeToEdgeEnforcement (针对 Android 15 及更高版本)

  1. 从 Android 15 开始,Google 正在逐步强制应用默认进入 Edge-to-edge 模式。然而,为了给开发者提供过渡时间,Android 15 (API 35) 引入了一个临时的 opt-out 属性:android:windowOptOutEdgeToEdgeEnforcement

    将此属性设置为 true 可以暂时避免应用被强制进入 Edge-to-edge 模式。但请注意,这是一个临时的解决方案,Google 明确表示这个属性在未来的 SDK 版本中会被废弃和移除。 因此,强烈建议最终还是适配 Edge-to-edge。

    示例 (themes.xml):

    ​ XML

    <style name="AppTheme" parent="Theme.Material3.DayNight.NoActionBar"><item name="android:windowOptOutEdgeToEdgeEnforcement">true</item><item name="android:statusBarColor">?attr/colorPrimaryVariant</item><item name="android:navigationBarColor">?attr/colorSurface</item>
    </style>
    

    你需要在 AndroidManifest.xml 中将你的 Activity 或 Application 的主题设置为包含此属性的主题。

    ​ XML

    <application...android:theme="@style/AppTheme"><activity android:name=".MainActivity" ... />
    </application>
    

3.4 对于特定的 View,使用 android:fitsSystemWindows="true" (局部或对于特定布局)

这个属性通常用于告诉 View 系统它应该为系统栏留出空间,从而避免内容被系统栏遮挡。当设置为 true 时,系统会自动为该 View 及其子 View 添加相应的 padding

如果你希望整个屏幕都避免 Edge-to-edge,那么将它设置在根布局上是可行的。然而,如果你的应用程序整体已经配置为 Edge-to-edge,那么这个属性只会影响设置它的 View 本身,而不是整个窗口。

示例 (activity_main.xml):

XML

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:fitsSystemWindows="true" > <TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!" /></LinearLayout>

总结和建议:

  • 长期来看,不推荐“避免进入 Edge-to-edge”。 Android 正在朝着更沉浸式体验的方向发展,尤其是在 Android 15 之后,Edge-to-edge 将成为默认行为。如果你不适配,你的应用可能会在不同设备上出现 UI 被遮挡或看起来过时的问题。
  • 最佳实践是适配 Edge-to-edge,并正确处理 WindowInsets 这意味着调用 enableEdgeToEdge()WindowCompat.setDecorFitsSystemWindows(window, false),然后使用 ViewCompat.setOnApplyWindowInsetsListener() 或 Compose 的 Modifier.windowInsetsPadding() 等来为关键 UI 元素添加适当的 padding
  • android:windowOptOutEdgeToEdgeEnforcement 是一个临时的“救命稻草”,如果你没有足够的时间立即适配 Edge-to-edge,可以在 Android 15 上使用它。但请记住它不是一个永久的解决方案。

​ 更进一步,Android 16 (API 36) 将移除之前Android 15中允许开发者暂时Opt-Out Edge-to-Edge行为的选项 (R.attr#windowOptOutEdgeToEdgeEnforcement) 。这意味着,对于目标SDK为36或更高版本的应用程序,将无法再选择退出Edge-to-Edge模式,从而强制所有新应用和更新的应用都必须适应这种全屏显示范式 。这种强制性行为强调了Edge-to-Edge是Android平台未来的标准UI行为,开发者必须将其视为应用程序设计和开发的基础要求。

四、旧版本Android的兼容性实现

 尽管Android 15及更高版本会自动启用Edge-to-Edge,但为了确保应用程序在更广泛的设备和Android版本上提供一致的沉浸式体验,开发者需要为旧版本Android(低于Android 15)或目标SDK低于35的应用手动实现兼容性。

最推荐的兼容性实现方式是使用 enableEdgeToEdge() 函数。此函数由 androidx.activity 库提供,能够自动配置应用程序的窗口,使其内容能够绘制到系统栏后面,并智能地调整系统栏的颜色和行为,以确保系统图标(如时间、电池)在应用程序背景上保持可见和对比度 。enableEdgeToEdge() 应该在 Activity 的 onCreate() 方法中,并且在调用 setContentView() 之前执行,以确保在视图加载之前,窗口已经被正确配置为全屏绘制 。
Kotlin 示例:

import androidx.activity.enableEdgeToEdge
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivityclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {enableEdgeToEdge() // 启用Edge-to-Edge模式super.onCreate(savedInstanceState)setContentView(R.layout.activity_main) // 或 setContent {... } for Compose}
}

Java 示例:

import androidx.activity.EdgeToEdge;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {EdgeToEdge.enable(this); // 启用Edge-to-Edge模式super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}
}

除了 enableEdgeToEdge(),开发者也可以通过 WindowCompat.setDecorFitsSystemWindows(window, false) 手动将应用程序内容布局到系统栏后面 。然而,enableEdgeToEdge() 是更推荐的方案,因为它不仅设置了全屏绘制,还会自动处理系统栏的颜色和行为,提供了更全面的兼容性解决方案 。
Kotlin 示例 (手动 WindowCompat):

import androidx.core.view.WindowCompat
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivityclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)WindowCompat.setDecorFitsSystemWindows(window, false) // 手动设置全屏绘制setContentView(R.layout.activity_main)}
}

Java 示例 (手动 WindowCompat):

import androidx.core.view.WindowCompat;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);WindowCompat.setDecorFitsSystemWindows(getWindow(), false); // 手动设置全屏绘制setContentView(R.layout.activity_main);}
}

此外,为了确保应用程序在软件键盘(IME)出现和消失时能够正确调整UI,避免输入框被键盘遮挡,开发者应在应用程序的 AndroidManifest.xml 文件中为相应的 Activity 设置 android:windowSoftInputMode=“adjustResize” 。此设置允许应用程序接收到软件键盘的尺寸作为Insets,从而在键盘弹出时自动调整布局,确保用户可以无障碍地进行输入 。

<activityandroid:name=".MainActivity"android:windowSoftInputMode="adjustResize"></activity>

五、 调试Edge-to-Edge布局问题

在实现Edge-to-Edge布局时,开发者可能会遇到各种UI问题。有效的调试对于确保应用程序提供无缝的用户体验至关重要。

5.1 常见问题识别

  1. 内容遮挡 (Content Overlap):
  • 系统栏遮挡: 应用程序的关键UI元素(如按钮、文本、图片)可能被状态栏(顶部)或导航栏(底部)覆盖,导致用户无法看到或交互 1。例如,Chrome浏览器在启用Edge-to-Edge后,有时会出现状态栏或导航按钮覆盖其工具栏的情况 12。
  • 显示切口遮挡: 在具有刘海屏或打孔屏的设备上,重要的UI内容可能被物理显示切口遮挡 1。
  • 键盘遮挡: 当软件键盘弹出时,输入框或相关UI元素可能被键盘覆盖,导致用户无法看到正在输入的内容或无法点击发送按钮 12。
  1. 手势冲突 (Gesture Conflicts):
  • 应用程序自定义的手势(如底部抽屉的滑动、游戏内的拖拽、轮播图的切换)可能与系统手势(如从屏幕边缘滑动返回、从底部上滑回到主页)发生冲突 1。这会导致用户操作不流畅,甚至误触系统功能。
  1. 动态UI调整问题 (Dynamic UI Adjustment Issues):
  • 键盘出现/消失: 应用程序未能平滑地响应键盘的出现和消失,导致UI跳动、闪烁或内容未正确调整 13。
  • 屏幕方向改变: 设备旋转时,应用程序的布局未能正确适应新的屏幕方向,可能导致UI元素错位或显示异常 15。

5.2 调试工具与方法

  1. Android Studio Layout Inspector (布局检查器):
  • Layout Inspector是Android Studio中一个强大的UI调试工具 16。它可以显示应用程序的视图层次结构,并允许开发者检查每个视图的属性 16。
  • 检查视图层次: 开发者可以查看UI元素的层级关系,确定哪些视图可能重叠或被遮挡。
  • 检查视图属性: 选择特定视图后,可以在“Attributes”面板中检查其布局参数、边距、填充等属性,从而验证是否正确应用了Insets 16。
  • 3D模式: Layout Inspector提供3D模式,允许开发者旋转和查看UI的层叠关系,这对于识别重叠问题非常有帮助 16。
  • 参考图像叠加: 开发者可以加载UI设计稿作为参考图像叠加在应用程序布局上,直观地比较实际布局与设计稿的差异,从而发现布局偏移或不符合设计规范的问题 16。
  • Compose检查: 对于使用Jetpack Compose构建的UI,Layout Inspector可以检查可组合项的重组频率,帮助识别导致性能问题的过度重组 16。
  1. ADB Commands (Android 调试桥命令):
  • ADB是与Android设备进行通信的命令行工具 17。虽然没有直接的ADB命令用于可视化Insets,但它在整体调试流程中扮演着重要角色。

  • adb logcat: 用于查看应用程序的日志输出,可以帮助开发者追踪Insets值的变化或应用程序在处理Insets时发生的错误 17。

  • 开发者选项 (Developer Options): 在设备的“开发者选项”中,有一些视觉调试工具可以辅助识别布局问题 18。

  • “显示布局边界” (Show layout bounds): 启用此选项会在屏幕上绘制每个视图的边界、边距和填充,帮助开发者直观地看到UI元素的实际占用空间和重叠情况。

  • “指针位置” (Pointer location): 显示屏幕上的触摸点及其坐标,有助于调试手势冲突区域。

  • “窗口动画缩放” (Window animation scale): 调整动画速度,有助于观察动态UI调整(如键盘弹出)的细节 18。

  • adb shell settings put global debug_view_attributes 1: Layout Inspector需要此全局设置才能正常工作,它会为设备上的所有进程生成额外的检查信息 16。

  1. 自定义可视化:
  • 在开发过程中,开发者可以在应用程序中添加临时的调试代码,例如绘制自定义的边框或半透明覆盖层来可视化Insets区域。这有助于在运行时直观地看到Insets对布局的影响。

5.3 调试流程

  1. 复现问题: 明确导致布局问题的操作步骤和设备状态(例如,特定屏幕方向、键盘弹出、手势操作)。
  2. 启用调试工具: 在Android Studio中启动Layout Inspector,并在设备上启用相关的开发者选项(如“显示布局边界”)。
  3. 观察与分析:
  • 使用Layout Inspector检查受影响UI元素的视图层次和属性。特别关注其padding、margin以及是否正确应用了WindowInsets。
  • 观察系统栏和显示切口的位置,以及它们与应用程序内容的相对关系。
  • 对于手势冲突,观察系统手势区域和应用程序手势区域的边界。
  1. 定位问题根源: 根据观察结果,判断是Insets未被应用、应用不正确、还是UI元素自身布局问题。例如,如果发现某个视图被导航栏遮挡,检查其底部填充或边距是否考虑了navigationBars或systemBars Insets。

  2. 修改与验证: 根据问题根源修改代码,然后重新运行应用程序并再次使用调试工具验证问题是否解决。

六、 避免Edge-to-Edge布局问题

为了确保应用程序在Edge-to-Edge模式下提供卓越的用户体验,开发者应遵循一系列最佳实践,并了解常见的陷阱及其解决方案。

6.1 最佳实践

  1. 使用Material Design组件 (Material Design Components):
  • 推荐使用Jetpack Compose的Material 3组件(androidx.compose.material3),如TopAppBar、BottomAppBar和NavigationBar,因为它们通常会自动处理系统栏的Insets,从而简化开发工作 6。
  • 对于基于View的应用程序,大多数Material Components(如BottomNavigationView、BottomAppBar)也能够自动处理Insets。然而,AppBarLayout等组件可能需要手动添加android:fitsSystemWindows="true"属性来处理顶部Insets 3。
  1. 精确的Inset应用 (Precise Inset Application):
  • 避免对整个根布局进行简单的全局填充,因为这可能导致不必要的空白区域,并失去Edge-to-Edge的沉浸感 5。

  • 应在组件级别精确应用Insets。

  • Jetpack Compose: 使用Modifier.windowInsetsPadding或其便捷方法(如Modifier.safeDrawingPadding()、Modifier.imePadding())来为特定可组合项添加填充 5。Scaffold组件的contentWindowInsets参数也提供了方便的Inset处理 6。对于滚动列表中的最后一个元素,可以使用Spacer结合Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)来确保其不被底部系统栏遮挡 5。

  • Views: 使用ViewCompat.setOnApplyWindowInsetsListener来监听窗口Insets的变化,并动态调整视图的边距或填充 3。

  1. 处理显示切口 (Handling Display Cutouts):
  • 确保背景和分隔线等非关键UI元素能够绘制到显示切口区域,以保持视觉连续性 1。
  • 关键UI元素(如文本、按钮、图标)应通过Insets进行内边距处理,以避免被显示切口遮挡 1。
  • 水平轮播图等可滚动内容应被设计为可以绘制到显示切口中 1。
  • 在AndroidManifest.xml中,非浮动窗口的layoutInDisplayCutoutMode应设置为LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS,以确保用户不会看到因切口导致的黑边 20。
  1. 管理系统栏颜色与透明度 (Managing System Bar Colors and Transparency):
  • 当UI在系统栏下方滚动时,状态栏应设置为半透明,以避免状态栏图标与内容混淆 1。
  • enableEdgeToEdge()函数会自动调整系统栏的颜色和图标,以适应系统主题(亮色/暗色)并确保对比度 3。
  • 如果需要手动控制系统栏图标颜色,可以使用WindowInsetsControllerCompat来设置isAppearanceLightStatusBars或isAppearanceLightNavigationBars 3。
  • 对于三键导航模式,默认情况下导航栏可能是半透明的。如果希望完全透明,可能需要设置window.isNavigationBarContrastEnforced = false 3。
  1. 优化滚动内容 (Optimizing Scrolling Content):
  • 对于RecyclerView或NestedScrollView,应设置android:clipToPadding=“false”,并使用Insets来添加底部填充,确保列表的最后一个元素或滚动内容的底部不会被导航栏遮挡 3。这样,内容在滚动时可以延伸到系统栏后面。
  1. 避免手势冲突区域的交互元素 (Avoiding Interactive Elements in Gesture Conflict Zones):
  • 避免在系统手势区域(由WindowInsets.systemGestures定义)放置可点击或可拖动的目标 1。这些区域是系统用于导航手势的,放置交互元素会导致手势冲突,影响用户体验 1。
  1. 响应式UI设计 (Responsive UI Design):
  • 应用程序应设计为能够适应各种屏幕方向、显示尺寸和宽高比 7。利用WindowInsets API是实现这一目标的关键,它允许UI动态地响应设备环境的变化。
  1. 测试与迭代 (Testing and Iteration)😗*
  • Edge-to-Edge布局的测试应是开发周期中持续进行的部分。在不同设备(包括模拟器和真机)、不同Android版本、不同系统导航模式(三键/手势)和不同显示切口类型上进行彻底测试 14。
  • 使用Android Studio的Layout Inspector等工具进行视觉调试,确保Insets被正确应用,没有内容遮挡或手势冲突 16。

6.2 常见陷阱与解决方案

  1. 陷阱:全局填充导致空白区域 (Global Padding Leading to Blank Spaces):
  • 描述: 开发者可能为了快速解决重叠问题,将safeDrawingPadding()或systemBars Insets应用于整个应用程序的根布局。这虽然可以防止内容被遮挡,但也会在系统栏区域创建不必要的空白,从而破坏Edge-to-Edge的沉浸感 5。
  • 解决方案: 实施组件级别的精确Inset应用。只在真正需要保护的UI元素上应用相应的Insets,例如,将safeDrawingPadding()应用于需要避开所有系统UI的可交互内容区域,而不是整个屏幕的背景 5。背景和非关键视觉元素应允许绘制到系统栏下方。
  1. 陷阱:键盘遮挡输入框 (Keyboard Obscuring Input Fields):
  • 描述: 当软件键盘弹出时,输入框或相关UI元素(如聊天界面的发送按钮)可能被键盘遮挡,导致用户无法看到输入内容或无法交互 8。

  • 解决方案:

  • 在AndroidManifest.xml中为Activity设置android:windowSoftInputMode=“adjustResize” 5。

  • 在Jetpack Compose中,使用Modifier.imePadding()或WindowInsets.ime来动态调整布局,确保输入框始终位于键盘上方 5。对于LazyColumn中的TextField,建议使用Modifier.imePadding()而不是contentPadding,并可能在列表末尾添加一个Spacer来确保TextField在键盘上方 5。

  • 对于Views,可以使用ViewCompat.setOnApplyWindowInsetsListener监听WindowInsetsCompat.Type.ime(),并相应调整视图的底部填充或边距 3。

  1. 陷阱:旧API兼容性问题 (Old API Compatibility Issues):
  • 描述: 应用程序可能仍在依赖Android 15之前用于控制系统窗口行为的旧API,例如android.view.Window.setDecorFitsSystemWindows或android.view.Window.setNavigationBarColor。这些API在Android 15及更高版本中已被弃用,或行为发生变化,可能导致意外的UI表现或兼容性问题 4。
  • 解决方案: 积极迁移到新的Insets API和androidx.core.view.WindowCompat、WindowInsetsControllerCompat等支持库 4。对于跨版本兼容性,优先使用enableEdgeToEdge()函数,它能够自动处理大部分兼容性细节 3。
  1. 陷阱:不透明系统栏导致视觉不协调 (Opaque System Bars Causing Visual Discrepancy):
  • 描述: 即使内容绘制到系统栏下方,如果系统栏本身仍然是不透明的,会破坏Edge-to-Edge的沉浸感,并可能导致视觉上的不协调 8。

  • 解决方案: 确保系统栏设置为透明或半透明。

  • 在styles.xml中设置android:statusBarColor和android:navigationBarColor为@android:color/transparent 8。

  • 使用enableEdgeToEdge(),它默认会使状态栏和手势导航栏透明,三键导航栏半透明 6。

  • 对于Views,可以通过ProtectionLayout和GradientProtection实现半透明状态栏,尤其是在滚动UI下方 1。

  1. 陷阱:过度嵌套ViewGroup (Excessive ViewGroup Nesting):
  • 描述: 在Views布局中,过度嵌套ViewGroup会导致UI层次结构过深,可能引发性能问题(如UI渲染卡顿)和布局计算错误 15。
  • 解决方案: 尽量保持视图层次扁平化。优先使用ConstraintLayout,它可以在不引入额外嵌套的情况下实现复杂的布局 15。

结论

​ Android Edge-to-Edge设计代表了移动UI体验的未来方向,它通过最大化屏幕利用率,为用户提供了前所未有的沉浸感和视觉流畅性。随着Android 15及更高版本对Edge-to-Edge行为的强制执行,以及旧API的逐步弃用,开发者必须将这种设计范式视为应用程序开发的基础要求,而不再是可选的优化。

​ 成功的Edge-to-Edge实现依赖于对Window Insets机制的深入理解和精确应用。这些Insets提供了关于系统UI和物理显示切口的详细尺寸信息,使开发者能够动态地调整UI布局,从而避免内容遮挡和手势冲突。无论是采用Jetpack Compose还是传统的Views,平台都提供了丰富的API和组件来辅助开发者处理Insets,例如Compose中的Modifier.windowInsetsPadding和Scaffold,以及Views中的ViewCompat.setOnApplyWindowInsetsListener和Material Components。

​ 为了避免常见的布局问题,开发者应遵循最佳实践,包括优先使用支持Insets的Material Design组件、在组件级别精确应用Insets、妥善处理显示切口、管理系统栏的透明度和颜色,以及优化滚动内容的显示。同时,积极利用Android Studio的Layout Inspector和ADB命令等调试工具,能够有效地识别和解决UI重叠、手势冲突和动态布局调整等问题。

​ 综上所述,Edge-to-Edge不仅是视觉上的升级,更是Android平台UI设计哲学的一次演进。它要求开发者从固定的、受限的布局思维转向动态的、响应式的设计方法。主动适应并精通Edge-to-Edge布局,将是确保应用程序在不断发展的Android生态系统中保持竞争力、提供卓越用户体验的关键。

fier.windowInsetsPadding和Scaffold,以及Views中的ViewCompat.setOnApplyWindowInsetsListener和Material Components。

​ 为了避免常见的布局问题,开发者应遵循最佳实践,包括优先使用支持Insets的Material Design组件、在组件级别精确应用Insets、妥善处理显示切口、管理系统栏的透明度和颜色,以及优化滚动内容的显示。同时,积极利用Android Studio的Layout Inspector和ADB命令等调试工具,能够有效地识别和解决UI重叠、手势冲突和动态布局调整等问题。

​ 综上所述,Edge-to-Edge不仅是视觉上的升级,更是Android平台UI设计哲学的一次演进。它要求开发者从固定的、受限的布局思维转向动态的、响应式的设计方法。主动适应并精通Edge-to-Edge布局,将是确保应用程序在不断发展的Android生态系统中保持竞争力、提供卓越用户体验的关键。

相关文章:

Android Edge-to-Edge

Android Edge-to-Edge显示&#xff1a;开发者综合指南 一、什么是Android Edge-to-Edge ​ Android Edge-to-Edge是一种先进的用户界面&#xff08;UI&#xff09;设计理念&#xff0c;旨在最大化利用设备的显示区域。它允许应用程序的内容延伸至屏幕的各个边缘&#xff0c;包…...

Java期末总复习 编程题(偏基础)

71. ①编写一个含 2 个属性的类&#xff0c;并为其设计有参构造方法&#xff0c;再设计一个用于显示属性值的方法。②编写该类的一个子类&#xff0c;除继承父类的 2 个属性外再增加一个属性&#xff0c;并创建有参构造方法对 3个属性初始化&#xff0c;重写显示属性的方法用于…...

进阶知识:自动化框架开发之有参的函数装饰器@wraps()和无参之间的对比

进阶知识&#xff1a;自动化框架开发之有参的函数装饰器wraps() 一、核心代码解析 1.1 有参装饰器结构 def func_3(argTrue): # 外层接收参数def inner_func(func): # 中间层接收被装饰函数wraps(func) # 保留元信息def wrap_func(*args, **kwargs): …...

es疑惑解读

好的&#xff0c;没问题。下面是我们对话中关于 Elasticsearch 数据库的知识点汇总&#xff0c;以问答对的形式呈现&#xff0c;希望能成为一个清晰的教程。 Elasticsearch 基础与 CRUD 操作 Q1: 我有 pymysql 的使用经验&#xff0c;想学习 Elasticsearch (ES) 的增删改查&am…...

Elasticsearch面试题带答案

Elasticsearch面试题带答案 Elasticsearch面试题及答案【最新版】Elasticsearch高级面试题大全(2025版),发现网上很多Elasticsearch面试题及答案整理都没有答案,所以花了很长时间搜集,本套Elasticsearch面试题大全,Elasticsearch面试题大汇总,有大量经典的Elasticsearch面…...

Linux 的 TCP 网络编程 -- 回显服务器,翻译服务器

目录 1. 相关函数介绍 1.1 listen() 1.2 accept() 1.3 connect() 2. TCP 回显服务器 2.1 Common.hpp 2.2 InetAddr.hpp 2.3 TcpClient.cc 2.4 TcpServer.hpp 2.5 TcpServer.cc 2.6 demo 测试 3. TCP 翻译服务器 3.1 demo 测试 1. 相关函数介绍 其中一些函数在之前…...

差动讯号(2):奇模与偶模

我们经常在探讨差动对时经常听到差模&#xff08;Differential mode&#xff09;与共模&#xff08;Common mode&#xff09;&#xff0c;究竟什么是差模&#xff1f; 什么是共模&#xff1f; 这一切就要从奇模&#xff08;Odd mode&#xff09;与偶模&#xff08;Even mode&am…...

口腔牙科小程序源码介绍

基于ThinkPHP、FastAdmin以及UniApp开发的口腔牙科小程序源码&#xff0c;专为口腔牙科行业设计&#xff0c;旨在提供一个便捷、高效的线上服务平台。 从技术层面看&#xff0c;这套源码结合了ThinkPHP的强大后端功能、FastAdmin的快速开发特性以及UniApp的跨平台优势&#xf…...

云计算与大数据进阶 | 27、存储系统如何突破容量天花板?可扩展架构的核心技术与实践—— 分布式、弹性扩展、高可用的底层逻辑(上)

数据中心里&#xff0c;存储系统是至关重要的组成部分。由于相关硬件组件与存储操作系统的多样性和复杂性&#xff0c;如何在保证存储稳定、安全、可靠的同时&#xff0c;实现灵活扩展和自服务&#xff0c;一直是困扰数据中心全面云化的难题。 简单来说&#xff0c;现在的难题…...

企业级物理服务器选型指南 - 网络架构优化篇

在分布式系统架构中&#xff0c;物理服务器的网络质量直接影响业务连续性。本文将通过真实场景演示如何选择符合业务特性的物理服务器。 一、网络拓扑设计原则 当企业需要覆盖多地域用户时&#xff0c;建议采用混合组网方案&#xff1a; # 网络质量检测脚本&#xff08;Pytho…...

可视化图解算法42:寻找峰值

牛客网 面试笔试TOP101 | LeetCode 162. 寻找峰值 1. 题目 描述 给定一个长度为n的数组nums&#xff0c;请你找到峰值并返回其索引。数组可能包含多个峰值&#xff0c;在这种情况下&#xff0c;返回任何一个所在位置即可。 1.峰值元素是指其值严格大…...

java每日精进 5.20【MyBatis 联表分页查询】

1. MyBatis XML 实现分页查询 1.1 实现方式 MyBatis XML 是一种传统的 MyBatis 使用方式&#xff0c;通过在 XML 文件中编写 SQL 语句&#xff0c;并结合 Mapper 接口和 Service 层实现分页查询。分页需要手动编写两条 SQL 语句&#xff1a;一条查询分页数据列表&#xff0c;…...

瀚高安全版4.5.8/4.5.9字符串默认按字节存储导致数据无法写入(APP)

文章目录 环境文档用途详细信息 环境 系统平台&#xff1a;Linux x86-64 Red Hat Enterprise Linux 7 版本&#xff1a;4.5 文档用途 解决安全版4.5.8/4.5.9字符串默认使用字节存储导致插入时提示数据超长。 详细信息 使用sysdba用户执行&#xff0c;重载配置或重启数据库…...

python新手学习笔记①

本笔记是根据Bilibili里的【3小时超快速入门Python | 动画教学【2025新版】【自学Python教程】【零基础Python】【计算机二级Python】【Python期末速成】】 https://www.bilibili.com/video/BV1Jgf6YvE8e/这个视频合集制作的代码笔记&#xff01; 1.字符串连接 运行结果 2.…...

用于管理共享内存的 C# 类 ShareMemory

可以在 Windows 和 Linux 上运行&#xff0c;利用了 .NET Core 的 System.IO.MemoryMappedFiles 库。这个类实现了共享内存的创建、打开、读取和写入功能。以下是对代码的一些分析和建议改进。 代码分析 初始化与打开共享内存: Init 方法用于创建新的共享内存段。OpenMem 方法…...

arcgispro双击打开没反应怎么办

不知道什么原因&#xff0c;突然就打不开了&#xff0c;网上关于arcgispro的教程和求助帖还比较少&#xff0c;参考了几个博主的分享&#xff0c;还是没解决 Arcpro——arcpro启动无反应_arcgispro正在初始化后没反应-CSDN博客 Arcgis Pro安装完成后启动失败的解决办法_arcgi…...

常见高速电路设计与信号完整性核心概念

一、传输线理论&#xff08;Transmission Line Theory&#xff09; 基本定义 当信号频率或边沿速率足够高时&#xff0c;互连线的长度与信号波长可比拟&#xff08;通常为信号上升时间的1/6以上&#xff09;&#xff0c;此时需将互连视为传输线&#xff0c;而非理想导线。 临界…...

青少年编程与数学 02-019 Rust 编程基础 20课题、面向对象

青少年编程与数学 02-019 Rust 编程基础 20课题、面向对象 一、面向对象的编程特性&#xff08;一&#xff09;封装&#xff08;Encapsulation&#xff09;&#xff08;二&#xff09;多态&#xff08;Polymorphism&#xff09;&#xff08;三&#xff09;继承&#xff08;Inhe…...

<uniapp><vuex><状态管理>在uniapp中,如何使用vuex实现数据共享与传递?

前言 本专栏是基于uniapp实现手机端各种小功能的程序&#xff0c;并且基于各种通讯协议如http、websocekt等&#xff0c;实现手机端作为客户端&#xff08;或者是手持机、PDA等&#xff09;&#xff0c;与服务端进行数据通讯的实例开发。 发文平台 CSDN 环境配置 系统&…...

如何使用通义灵码辅助开发鸿蒙OS - AI编程助手提升效率

一、引言 鸿蒙 OS 是华为推出的一款面向全场景的分布式操作系统&#xff0c;其开发应用主要使用华为基于 IntelliJ IDEA 定制的 DevEco Studio。然而&#xff0c;DevEco Studio 的插件生态相对有限&#xff0c;为了提升开发效率和代码质量&#xff0c;我们可以借助通义灵码这一…...

解决git中断显示中文为八进制编码问题

git config --global core.quotepath false 命令用于配置 Git 如何处理非 ASCII 字符&#xff08;如中文、日文、韩文等&#xff09;的文件名显示 core.quotepath Git 的一个核心配置项&#xff0c;控制是否对非 ASCII 文件名进行转义&#xff08;quote&#xff09;处理。 f…...

宿州金博学校开展防震演练:夯实安全根基,守护校园平安

5月13日上午9点30分&#xff0c;金博学校原本宁静的校园被一阵急促的警报声打破&#xff0c;一场精心筹备、紧张有序的防震演练正式开启。本次演练意义重大&#xff0c;旨在强化全体师生的防震减灾意识&#xff0c;提高大家在地震突发时的应急反应与自我保护能力。 紧急避险&am…...

【鸿蒙开发】安全

应用隐私保护最佳实践 使用隐私声明获取用户同意 初次访问使用隐私声明弹窗&#xff0c;只有用户同意后才能开始正常使用。 减少应用的位置访问权限 使用模糊定位获取位置信息 位置权限申请方式 target API level申请位置权限申请结果位置的精确度小于9ohos.permission.L…...

企业级网络安全护盾:剖析高防IP原理与防护策略

在当今数字化时代&#xff0c;网络安全已成为企业不可忽视的关键课题。高防IP作为网络安全防护的重要手段之一&#xff0c;正因其出色的防御能力和应用灵活性受到广泛关注。本文将深入解析高防IP的原理&#xff0c;包括流量清洗、防御策略、节点分布等技术要点&#xff0c;并通…...

智能事件分析边缘服务器:交通管理与安全监测的利器

在当今交通管理和安全监测的领域中&#xff0c;智能化、高效化的设备需求日益增长。智能事件分析边缘服务器凭借其卓越的性能和丰富的功能&#xff0c;成为了该领域的佼佼者。 一、产品概述 智能事件分析边缘服务器是一款采用嵌入式 Linux 操作系统的边缘事件分析终端。它具有…...

Gin--Blog项目-flags文件解析

flags/enter.go文件解析 package flagsimport ("flag""os" )type Options struct {File stringDB boolVersion bool }var FlagOptions new(Options)func Parse() {flag.StringVar(&FlagOptions.File, "f", "settings.yaml&qu…...

JVM的面试相关问题

面试中的相关问题主要是三块 1.JVM 内存区域划分 2.JVM 的类加载机制 3.JVM 的垃圾回收机制 JVM Java虚拟机 VM Virtual Machine 虚拟机,用 软件 来 模拟 硬件 传统意义上的"虚拟机" 更多指的是 VMWare, Virtual Box, Hyper-V, KVM(构造出虚拟的电脑,甚至可以…...

Linux(3)——基础开发工具

一、软件包管理器——yum 1.Linux下安装程序的方式 在Linux环境下安装软件的方式有以下几个方式&#xff1a; 1&#xff09;源码安装&#xff0c;直接下载源代码&#xff0c;让它自行编译运行形成可执行程序。 2&#xff09;软件包安装&#xff0c;下载rpm安装包&#xff0…...

HarmonyOS5云服务技术分享--ArkTS调用函数

✨【HarmonyOS实战指南】手把手教你用ArkTS玩转云函数文件获取✨ 大家好呀今天我们来聊聊如何通过HarmonyOS的ArkTS语言实现云函数文件获取功能。整个过程就像搭积木一样有趣&#xff0c;保证小白也能轻松上手&#xff01;&#xff08;文末有完整代码模板哦&#xff09; &…...

2025年AI搜索引擎发展洞察:技术革新与市场变革

引言&#xff1a;AI搜索的崛起与市场格局重塑 2024-2025年&#xff0c;AI搜索市场迎来了前所未有的变革期。随着DeepSeek-R1等先进大语言模型的推出&#xff0c;传统搜索引擎、AI原生搜索平台以及各类内容平台纷纷加速智能化转型&#xff0c;推动搜索技术从基础信息检索向深度…...

基于开源链动2+1模式AI智能名片S2B2C商城小程序的社群构建与新型消费迎合策略研究

摘要&#xff1a;随着个性化与小众化消费的崛起&#xff0c;消费者消费心理和模式发生巨大变化&#xff0c;社群构建对商家迎合新型消费特点、融入市场经济发展至关重要。开源链动21模式AI智能名片S2B2C商城小程序的出现&#xff0c;为社群构建提供了创新工具。本文探讨该小程序…...

leetcode 旋转数组 java

本来想用栈或者队列来解决&#xff0c;发现一直报k>nums.length的错。 将原数组下标为 i 的元素放至新数组下标为 (ik)modn 的位置&#xff0c;最后将新数组拷贝至原数组即可。 class Solution {public void rotate(int[] nums, int k) {// Stack<Integer> stack n…...

Ansible模块——通过 URL 下载文件

通过 URL 下载文件 ansible.builtin.get_url 可以通过 URL 下载文件。 选项名 类型 默认值 描述 attributesstrnull 设置文件系统对象的属性&#xff0c;格式参考 lsattr&#xff1b;支持 , -, 操作符。别名&#xff1a;attr。 backupboolfalse 创建目标文件的备份副本&am…...

2025年高考考务人员培训监考员学习项目试题

考务人员培训系统 学员端&#xff08;高考&#xff09; 第1部分&#xff1a;单选题 1. 对违背考试公平、公正原则&#xff0c;在考试中存在违规行为的考生&#xff0c;采用何种处理办法&#xff1f;&#xff08;A &#xff09; [2分] A. 根据《国家教育考试违规处理办法》等…...

谈谈jvm的调优思路

目录 1、G1回收器 2、常用的回收器分类 1、cms 2、G1、Hotspot 3、ZGC 4、设置 3、常见的调优策略 3.1、设定大小 1、堆的大小 2、Region的大小 3、年轻代大小调整 3.2、设置最大停顿时间 3.3、设置标记和回收线程 3.4、并发周期触发阈值 背景 正常情况下&#x…...

通过自签名ssl证书进行js注入的技术,适合注入electron开发的app

由于很多软件都是electron或者pyqt做的安装包,没法像浏览器那样可以直接通过浏览器插件注入js,或者很多网站都有csp限制,无法直接注入js,这种使用自签名代理的方式,完美绕过了所有限制,直接将js注入到外链js中。 步骤:1,局域网准备两台电脑,一个windows,一台Linux,…...

异步复位,同步释放

参考链接&#xff1a;数字电路复位信号设计&#xff08;异步复位、同步释放&#xff09;笔记详解_异步复位同步释放的高有效原理-CSDN博客 一、异步复位&#xff08;Asynchronous Reset&#xff09; 含义&#xff1a;当复位信号 reset 为低&#xff08;或高&#xff0c;视具体…...

Vortex GPGPU的github流程跑通与功能模块波形探索(三)

文章目录 前言一、./build/ci下的文件结构二、基于驱动进行仿真过程牵扯的文件2.1 blackbox.sh文件2.2 demo文件2.3 额外牵扯到的ramulator2.3.1 ramulator简单介绍2.3.2 ramulator使用方法2.3.3 ramulator的输出2.3.4 ramulator的复现2.3.4.1 调试与验证&#xff08;第 4.1 节…...

Ubuntu 安装 Node.js 指定版本指南

Ubuntu 安装 Node.js 指定版本指南&#xff08;适用于生产与开发环境&#xff09; 在没有安装 NVM 的服务器环境中&#xff08;如 Docker、CI/CD、虚拟机等&#xff09;&#xff0c;建议使用 Node.js 官方的二进制包源&#xff08;PPA&#xff09;来快速安装特定版本的 Node.j…...

使用 Java 开发 Android 应用:Kotlin 与 Java 的混合编程

使用 Java 开发 Android 应用&#xff1a;Kotlin 与 Java 的混合编程 在开发 Android 应用程序时&#xff0c;我们通常可以选择使用 Java 或 Kotlin 作为主要的编程语言。然而&#xff0c;有些开发者可能会想要在同一个项目中同时使用这两种语言&#xff0c;这就是所谓的混合编…...

安防监控网络摄像机画面异常问题与视频监控管理平台EasyCVR应用

一、方案背景 在安防监控领域&#xff0c;画面卡顿、时有时无等问题犹如隐藏的潜在风险点&#xff0c;不仅严重干扰监控系统的正常运行&#xff0c;更可能在安全防护的关键时刻出现故障&#xff0c;让潜在的风险与隐患有机可乘。想要彻底攻克这些顽疾&#xff0c;就需要我们抽…...

MATLAB中进行语音信号分析

在MATLAB中进行语音信号分析是一个涉及多个步骤的过程&#xff0c;包括时域和频域分析、加窗、降噪滤波、端点检测以及特征提取等。 1. 加载和预览语音信号 首先&#xff0c;你需要加载一个语音信号文件。MATLAB支持多种音频文件格式&#xff0c;如.wav。 [y, fs] audiorea…...

Kotlin 协程 (三)

协程通信是协程之间进行数据交换和同步的关键机制。Kotlin 协程提供了多种通信方式&#xff0c;使得协程能够高效、安全地进行交互。以下是对协程通信的详细讲解&#xff0c;包括常见的通信原语、使用场景和示例代码。 1.1 Channel 定义&#xff1a;Channel 是一个消息队列&a…...

AI 商业化部署中,ollama 和 vllm 的选型对比

介绍 ollama Ollama是指一个开源的大模型服务工具&#xff0c;旨在简化大型语言模型&#xff08;LLM&#xff09;的本地部署、运行和管理。它让用户能够在本地设备上轻松运行和管理各种大语言模型&#xff0c;无需依赖云端服务。 vllm 在深度学习推理领域&#xff0c;vLLM框…...

mysql的乐观锁与悲观锁

1.悲观锁 含义&#xff1a;假设会发生冲突&#xff0c;因此在操作数据之前对数据加锁&#xff0c;确保其他事务无法访问该数据。 应用场景&#xff1a;适用于并发冲突多&#xff0c;写多读少的场景&#xff0c;通过加锁的方式确保数据的安全性。 实现方式&#xff1a;使用行…...

进程——概念及状态

目录 概念 介绍 举例 进程状态 概念 解释 实例 R S T t Z 孤儿进程 概念 介绍 大多数初学者会认为进程就是从硬盘加载到内存的可执行文件&#xff08;当可执行文件被加载到内存里称为程序&#xff09;&#xff0c;实际上并不是这样的&#xff0c;进程其实是操作系…...

服务器数据恢复—Linux系统服务器崩溃且重装系统的数据恢复案例

服务器数据恢复环境&#xff1a; linux操作系统服务器中有一组由4块SAS接口硬盘组建的raid5阵列。 服务器故障&#xff1a; 服务器工作过程中突然崩溃。管理员将服务器操作系统进行了重装。 用户方需要恢复服务器中的数据库、办公文档、代码文件等。 服务器数据恢复过程&#…...

【git】git commit模板

【git】git commit模板 目录 【git】git commit模板1.使用git commit 模板操作步骤&#xff1a;使用示例&#xff1a; 2. gitlab merge 模板 1.使用git commit 模板 操作步骤&#xff1a; 设置模板路径,其中path就是commit模板路径 git config --global commit.template path设…...

IGBT选型时需关注的参数,适用场景(高压大电流低频)以及驱动电路设计注意事项

概述 IGBT&#xff08;绝缘栅双极型晶体管&#xff09;是电力控制和电力转换的核心器件&#xff0c;是由BJT&#xff08;双极型晶体管&#xff09;和MOS&#xff08;绝缘栅型场效应管&#xff09;组成的复合全控型电压驱动式功率半导体器件。有高输入阻抗&#xff08;MOSFET优点…...

hghac集群服务器时间同步(chrony同步)

文章目录 环境文档用途详细信息 环境 系统平台&#xff1a;银河麒麟&#xff08;龙芯&#xff09;svs,银河麒麟 &#xff08;X86_64&#xff09;,银河麒麟 &#xff08;飞腾&#xff09;,银河麒麟 &#xff08;鲲鹏&#xff09;,银河麒麟 &#xff08;海光&#xff09;,银河麒…...