HarmonyOS角落里的知识:“开发应用沉浸式效果”

概述

典型应用全屏窗口UI元素包括状态栏、应用界面和底部导航条。开发应用沉浸式效果主要指通过调整状态栏、应用界面和导航条的显示效果来减少状态栏导航条等系统界面的突兀感,从而使用户获得最佳的UI体验。

图1 界面元素示意图

开发应用沉浸式效果主要要考虑如下几个设计要素:

  • UI元素避让处理:导航条底部区域可以响应点击事件,除此之外的可交互UI元素和应用关键信息不建议放到导航条区域。
  • 沉浸式效果处理:将状态栏和导航条颜色与界面元素颜色相匹配,不出现明显的突兀感。

针对上面的设计要求,可以通过如下两种方式实现应用沉浸式效果:

  • 窗口全屏布局方案:调整布局系统为全屏布局,界面元素延伸到状态栏和导航条区域实现沉浸式效果,然后通过接口查询状态栏和导航条区域进行可交互元素避让处理。
  • 组件安全区方案:布局系统保持安全区内布局(安全区:界面上排除状态栏和导航条区域),然后通过接口延伸绘制内容(如背景色,背景图)到状态栏和导航条区域实现沉浸式效果。

    该方案下,界面元素仅做绘制延伸,无法单独布局到状态栏和导航条区域,针对需要单独布局UI元素到状态栏和导航条区域的场景建议使用窗口全屏布局方案处理。

窗口全屏布局方案

窗口全屏布局方案主要涉及以下应用扩展布局,全屏显示和应用扩展布局,隐藏避让区两个应用场景。

应用扩展布局,全屏显示

可以通过调用窗口强制全屏布局接口(setWindowLayoutFullScreen())实现界面元素覆盖到状态栏和导航条,获取到状态栏和导航条高度后进行避让处理。

该布局方案相对灵活,开发者可以通过获取到状态栏和导航条的区域,从而进行避让处理。

  1. 调用setWindowLayoutFullScreen()接口设置窗口全屏。
    // EntryAbility.ets
    import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
    import { window } from '@kit.ArkUI';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    export default class EntryAbility extends UIAbility {
      // ...
    
      onWindowStageCreate(windowStage: window.WindowStage): void {
        windowStage.loadContent('pages/Index', (err, data) => {
          if (err.code) {
            return;
          }
    
          let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
          // 1. 设置窗口全屏
          let isLayoutFullScreen = true;
          windowClass.setWindowLayoutFullScreen(isLayoutFullScreen)
            .then(() => {
              console.info('Succeeded in setting the window layout to full-screen mode.');
            })
            .catch((err: BusinessError) => {
              console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(err));
            });
        });
      }
    }
  2. 使用getWindowAvoidArea()接口获取布局遮挡区域(例如状态栏、导航条)。
    // EntryAbility.ets
    import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
    import { window } from '@kit.ArkUI';
    
    export default class EntryAbility extends UIAbility {
      // ...
    
      onWindowStageCreate(windowStage: window.WindowStage): void {
        windowStage.loadContent('pages/Index', (err, data) => {
          if (err.code) {
            return;
          }
    
          let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
          // 1. 设置窗口全屏
          // ...
    
          // 2. 获取布局避让遮挡的区域
          let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // 以导航条避让为例
          let avoidArea = windowClass.getWindowAvoidArea(type);
          let bottomRectHeight = avoidArea.bottomRect.height; // 获取到导航条区域的高度
          AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
        });
      }
    }
  3. 在布局中对具体控件布局避让遮挡的区域。例如对底部Tab组件增加对应高度或设置margin边距,底部若是List组件可增加一个空节点。
    let storage = LocalStorage.getShared();
    
    @Entry(storage)
    @Component
    struct Index {
      bottomRectHeight: string = AppStorage.get<number>('bottomRectHeight') + 'px';
    
      build() {
        Row() {
          Column() {
            Row() {
              Text('ROW1').fontSize(40)
            }.backgroundColor(Color.Orange).padding(20)
    
            Row() {
              Text('ROW2').fontSize(40)
            }.backgroundColor(Color.Orange).padding(20)
    
            Row() {
              Text('ROW3').fontSize(40)
            }.backgroundColor(Color.Orange).padding(20)
    
            Row() {
              Text('ROW4').fontSize(40)
            }.backgroundColor(Color.Orange).padding(20)
    
            Row() {
              Text('ROW5').fontSize(40)
            }.backgroundColor(Color.Orange).padding(20)
    
            Row() {
              Text('ROW6').fontSize(40)
            }.backgroundColor(Color.Orange).padding(20)
          }
          .width('100%')
          .height('100%')
          .alignItems(HorizontalAlign.Center)
          .justifyContent(FlexAlign.SpaceBetween)
          .backgroundColor('#008000')
        }
        .margin({ bottom: this.bottomRectHeight }) // 此处margin具体数值在实际中应与导航条区域高度保持一致
      }
    }

应用扩展布局,隐藏避让区

此场景下导航条会自动隐藏,适用于游戏、电影等应用场景。可以通过从底部上滑唤出导航条。

  1. 调用setWindowLayoutFullScreen()接口设置窗口全屏。
    import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
    import { window } from '@kit.ArkUI';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    export default class EntryAbility extends UIAbility {
      // ...
    
      onWindowStageCreate(windowStage: window.WindowStage): void {
        windowStage.loadContent('pages/Index', (err, data) => {
          if (err.code) {
            return;
          }
    
          let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
          // 1. 设置窗口全屏
          let isLayoutFullScreen = true;
          windowClass.setWindowLayoutFullScreen(isLayoutFullScreen)
            .then(() => {
              console.info('Succeeded in setting the window layout to full-screen mode.');
            })
            .catch((err: BusinessError) => {
              console.error(`Failed to set the window layout to full-screen mode. Code is ${err.code}, message is ${err.message}`);
            });
        });
      }
    }
  2. 调用setSpecificSystemBarEnabled()接口设置状态栏和导航条的具体显示/隐藏状态,此场景下将其设置为隐藏。
    import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
    import { window } from '@kit.ArkUI';
    import { BusinessError } from '@kit.BasicServicesKit';
    
    export default class EntryAbility extends UIAbility {
      // ...
    
      onWindowStageCreate(windowStage: window.WindowStage): void {
        windowStage.loadContent('pages/Index', (err, data) => {
          if (err.code) {
            return;
          }
    
          let windowClass: window.Window = windowStage.getMainWindowSync(); // 获取应用主窗口
          // 1. 设置窗口全屏
          // ...
    
          // 2. 设置状态栏和导航条隐藏
          windowClass.setSpecificSystemBarEnabled('status', false)
            .then(() => {
              console.info('Succeeded in setting the status bar to be invisible.');
            })
            .catch((err: BusinessError) => {
              console.error(`Failed to set the status bar to be invisible. Code is ${err.code}, message is ${err.message}`);
            });
        });
      }
    }
  3. 在界面中无需进行导航条避让操作。
    @Entry()
    @Component
    struct Index {
      build() {
        Row() {
          Column() {
            Row() {
              Text('ROW1').fontSize(40)
            }.backgroundColor(Color.Orange).padding(20)
    
            Row() {
              Text('ROW2').fontSize(40)
            }.backgroundColor(Color.Orange).padding(20)
    
            Row() {
              Text('ROW3').fontSize(40)
            }.backgroundColor(Color.Orange).padding(20)
    
            Row() {
              Text('ROW4').fontSize(40)
            }.backgroundColor(Color.Orange).padding(20)
    
            Row() {
              Text('ROW5').fontSize(40)
            }.backgroundColor(Color.Orange).padding(20)
    
            Row() {
              Text('ROW6').fontSize(40)
            }.backgroundColor(Color.Orange).padding(20)
          }
          .width('100%')
          .height('100%')
          .alignItems(HorizontalAlign.Center)
          .justifyContent(FlexAlign.SpaceBetween)
          .backgroundColor('#008000')
        }
      }
    }

组件安全区方案

应用未使用setWindowLayoutFullScreen()接口设置窗口全屏布局时,默认使能组件安全区布局。

应用在默认情况下窗口背景绘制范围是全屏,但UI元素被限制在安全区内(自动排除状态栏和导航条)进行布局,来避免界面元素被状态栏和导航条遮盖。

图2 界面元素自动避让状态栏和导航条示意图

针对状态栏和导航条颜色与界面元素颜色不匹配问题,可以通过如下两种方式实现沉浸式效果:

  • 状态栏和导航条颜色相同场景,可以通过设置窗口的背景色来实现沉浸式效果。窗口背景色可通过setWindowBackgroundColor()进行设置。
    import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
    import { window } from '@kit.ArkUI';
    
    export default class EntryAbility extends UIAbility {
      // ...
    
      onWindowStageCreate(windowStage: window.WindowStage): void {
        windowStage.loadContent('pages/Index', (err, data) => {
          if (err.code) {
            return;
          }
    
          // 设置全窗颜色和应用元素颜色一致
          windowStage.getMainWindowSync().setWindowBackgroundColor('#008000');
        });
      }
    }

    界面状态栏和导航条颜色相同场景。

    // xxx.ets
    @Entry
    @Component
    struct Example {
      build() {
        Column() {
          Row() {
            Text('ROW1').fontSize(40)
          }.backgroundColor(Color.Orange).padding(20)
    
          Row() {
            Text('ROW2').fontSize(40)
          }.backgroundColor(Color.Orange).padding(20)
    
          Row() {
            Text('ROW3').fontSize(40)
          }.backgroundColor(Color.Orange).padding(20)
    
          Row() {
            Text('ROW4').fontSize(40)
          }.backgroundColor(Color.Orange).padding(20)
    
          Row() {
            Text('ROW5').fontSize(40)
          }.backgroundColor(Color.Orange).padding(20)
    
          Row() {
            Text('ROW6').fontSize(40)
          }.backgroundColor(Color.Orange).padding(20)
        }
        .width('100%')
        .height('100%')
        .alignItems(HorizontalAlign.Center)
        .justifyContent(FlexAlign.SpaceBetween)
        .backgroundColor('#008000')
      }
    }

  • 状态栏和导航条颜色不同时,可以使用expandSafeArea属性扩展安全区域属性进行调整。
    // xxx.ets
    @Entry
    @Component
    struct Example {
      build() {
        Column() {
          Row() {
            Text('Top Row').fontSize(40).textAlign(TextAlign.Center).width('100%')
          }
          .backgroundColor('#F08080')
          // 设置顶部绘制延伸到状态栏
          .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
    
          Row() {
            Text('ROW2').fontSize(40)
          }.backgroundColor(Color.Orange).padding(20)
    
          Row() {
            Text('ROW3').fontSize(40)
          }.backgroundColor(Color.Orange).padding(20)
    
          Row() {
            Text('ROW4').fontSize(40)
          }.backgroundColor(Color.Orange).padding(20)
    
          Row() {
            Text('ROW5').fontSize(40)
          }.backgroundColor(Color.Orange).padding(20)
    
          Row() {
            Text('Bottom Row').fontSize(40).textAlign(TextAlign.Center).width('100%')
          }
          .backgroundColor(Color.Orange)
          // 设置底部绘制延伸到导航条
          .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
        }
        .width('100%').height('100%').alignItems(HorizontalAlign.Center)
        .backgroundColor('#008000')
        .justifyContent(FlexAlign.SpaceBetween)
      }
    }

扩展安全区域属性原理

  • 布局阶段按照安全区范围大小进行UI元素布局。
  • 布局完成后查看设置了expandSafeArea的组件边界(不包括margin)是否和安全区边界相交。
  • 如果设置了expandSafeArea的组件和安全区边界相交,根据expandSafeArea传递的属性则进一步扩大组件绘制区域大小覆盖状态栏、导航条这些非安全区域。
  • 上述过程仅改变组件自身绘制大小,不进行二次布局,不影响子节点和兄弟节点的大小和位置。
  • 子节点可以单独设置该属性,只需要自身边界和安全区域重合就可以延伸自身大小至非安全区域内,需要确保父组件未设置clip等裁切属性。
  • 配置expandSafeArea属性组件进行绘制扩展时,需要关注组件不能配置固定宽高尺寸,百分比除外。

背景图和视频场景

设置背景图、视频控件大小为安全区域大小并配置expandSafeArea属性。

// xxx.ets
@Entry
@Component
struct SafeAreaExample1 {
  build() {
    Stack() {
      Image($r('app.media.bg'))
        .height('100%').width('100%')
        .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]) // 图片组件的绘制区域扩展至状态栏和导航条。
    }.height('100%').width('100%')
  }
}

滚动类场景

要求需要List滚动类组件滚动过程中元素可以和导航条重合,滚动至底部时,元素在导航条上面需要避让。

由于expandSafeArea不改变子节点布局,故List等滚动类控件可以调用expandSafeArea特性延伸List组件视图窗口大小而不改变ListItem内在布局,实现ListItem在滑动过程中显示在导航条下,但滚动至最后一个时显示在导航条上,示意图如下:

图3 未适配时列表下方被导航条遮盖

图4 List配置expandSafeArea属性后的效果

仅扩展底部导航条。

  1. 配置窗口整体底色。
    import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
    import { window } from '@kit.ArkUI';
    
    export default class EntryAbility extends UIAbility {
      // ...
    
      onWindowStageCreate(windowStage: window.WindowStage): void {
        windowStage.loadContent('pages/Index', (err, data) => {
          if (err.code) {
            return;
          }
    
          windowStage.getMainWindowSync().setWindowBackgroundColor('#DCDCDC'); // 配置窗口整体底色
        });
      }
    }
  2. 界面代码展示。
    // xxx.ets
    @Entry
    @Component
    struct ListExample {
      private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
      build() {
        Column() {
          List({ space: 20, initialIndex: 0 }) {
            ForEach(this.arr, (item: number) => {
              ListItem() {
                Text('' + item)
                  .width('100%')
                  .height(100)
                  .fontSize(16)
                  .textAlign(TextAlign.Center)
                  .borderRadius(10)
                  .backgroundColor(0xFFFFFF)
              }
            }, (item: string) => item)
          }
          .listDirection(Axis.Vertical) // 排列方向
          .scrollBar(BarState.Off)
          .friction(0.6)
          .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线
          .edgeEffect(EdgeEffect.Spring) // 边缘效果设置为Spring
          .width('90%')
          // List组件的视窗范围扩展至导航条。
          .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM])
        }
        .width('100%')
        .height('100%')
        .padding({ top: 15 })
      }
    }

底部页签场景

要求页签背景色能够延伸到导航条区域,但页签内部可操作元素需要在导航条之上。

针对底部的页签部分,Navigation组件和Tabs组件默认实现了页签的延伸处理,开发者只需要保证Navigation和Tabs组件的底部边界和底部导航条重合即可。若开发者显式调用expandSafeArea接口,则安全区效果由expandSafeArea参数指定。

如果未使用上述组件而是采用自定义方式实现页签的场景,可以针对底部元素设置expandSafeArea属性实现底部元素的背景扩展。

图5 顶部和底部UI元素未设置和设置expandSafeArea属性效果对比

// xxx.ets
@Entry
@Component
struct VideoCreateComponent {
  build() {
    Column() {
      Row() {
        Text('Top Row').fontSize(40).textAlign(TextAlign.Center).width('100%')
      }
      .backgroundColor('#F08080')
      // 设置顶部绘制延伸到状态栏
      .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])

      Row() {
        Text('ROW2').fontSize(40)
      }.backgroundColor(Color.Orange).padding(20)

      Row() {
        Text('ROW3').fontSize(40)
      }.backgroundColor(Color.Orange).padding(20)

      Row() {
        Text('ROW4').fontSize(40)
      }.backgroundColor(Color.Orange).padding(20)

      Row() {
        Text('ROW5').fontSize(40)
      }.backgroundColor(Color.Orange).padding(20)

      Row() {
        Text('Bottom Row').fontSize(40).textAlign(TextAlign.Center).width('100%')
      }
      .backgroundColor(Color.Orange)
      // 设置底部绘制延伸到导航条
      .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
    }
    .width('100%').height('100%').alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.SpaceBetween)
    .backgroundColor(Color.Green)
  }
}

图文场景

当状态栏元素和底部导航条元素不同时,无法单纯通过窗口背景色或者背景图组件延伸实现,此时需要对顶部元素和底部元素分别配置expandSafeArea属性,顶部元素配置expandSafeArea([SafeAreaType.SYSTEM],[SafeAreaEdge.TOP]),底部元素配置expandSafeArea([SafeAreaType.SYSTEM],[SafeAreaEdge.BOTTOM])。

 
@Entry
@Component
struct Index {
  build() {
    Swiper() {
      Column() {
        Image($r('app.media.start'))
          .height('50%').width('100%')
          // 设置图片延伸到状态栏
          .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
        Column() {
          Text('HarmonyOS 第一课')
            .fontSize(32)
            .margin(30)
          Text('通过循序渐进的学习路径,无经验和有经验的开发者都可以掌握ArkTS语言声明式开发范式,体验更简洁、更友好的HarmonyOS应用开发旅程。')
            .fontSize(20).margin(20)
        }.height('50%').width('100%')
        .backgroundColor(Color.White)
        // 设置文本内容区背景延伸到导航栏
        .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
      }
    }
    .width('100%')
    .height('100%')
    // 关闭Swiper组件默认的裁切效果以便子节点可以绘制在Swiper外。
    .clip(false)
  }
}



最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?但是又不知道从哪里下手,而且学习时频繁踩坑,最终浪费大量时间。所以本人整理了一些比较合适的鸿蒙(HarmonyOS NEXT)学习路径和一些资料的整理供小伙伴学习

点击领取→纯血鸿蒙Next全套最新学习资料(安全链接,放心点击

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

一、鸿蒙(HarmonyOS NEXT)最新学习路线

有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)…等技术知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

二、HarmonyOS Next 最新全套视频教程

三、《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

四、大厂面试必问面试题

五、鸿蒙南向开发技术

六、鸿蒙APP开发必备

七、鸿蒙生态应用开发白皮书V2.0PDF


完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结
总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

                        

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

心灵馆咨询系统小程序心理咨询平台聊天咨询

心灵馆咨询系统小程序&#xff1a;解锁你的心灵密码 &#x1f496; 心灵之旅的导航者 在繁忙的现代生活中&#xff0c;我们时常会面临各种压力与困惑。心灵馆咨询系统小程序&#xff0c;如同一位贴心的导航者&#xff0c;引领我们探索内心的世界&#xff0c;寻找真正的自我。 …

DDP(Differential Dynamic Programming)算法举例

DDP(Differential Dynamic Programming)算法 基本原理 DDP(Differential Dynamic Programming)是一种用于求解非线性最优控制问题的递归算法。它基于动态规划的思想,通过线性化系统的动力学方程和二次近似代价函数,递归地优化控制策略。DDP的核心在于利用局部二次近似来…

北大医院副院长李建平:用AI解决临床心肌缺血预测的难点、卡点和痛点

2024年6月14日&#xff0c;第六届北京智源大会在中关村展示中心开幕&#xff0c;海内外的专家学者围绕人工智能关键技术路径和应用场景&#xff0c;展开了精彩演讲与尖峰对话。在「智慧医疗和生物系统&#xff1a;影像、功能与仿真」论坛上&#xff0c;北京大学第一医院副院长、…

[经典]原型资源:蚂蚁金服UI模版部件库

部件库预览链接&#xff1a; https://d3ttsx.axshare.com 支持版本: Axrure RP 8 文件大小: 30MB 文档内容介绍 基本部件&#xff1a;表单样式&#xff1a;12款、数据样式&#xff1a;10款、服务样式&#xff1a;6款、导航&#xff1a;5款、业务组件&#xff1a;7款、 模板…

区块链技术与数字货币

1.起源 ➢中本聪(Satoshi Nakamoto), 2008 ➢比特币:一种点对点的电子现金系统 2.分布式账本技术原理 1.两个核心技术&#xff1a; ➢以链式区块组织账本数据实现账本数据的不可篡改 ➢分布式的可信记账机制 2.共识机制&#xff1a;由谁记账 ➢目的&#xff1a; ⚫ 解…

鸿蒙开发系统基础能力:【@ohos.hiTraceMeter (性能打点)】

性能打点 本模块提供了追踪进程轨迹&#xff0c;度量程序执行性能的打点能力。本模块打点的数据供hiTraceMeter工具分析使用。 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 impor…

AcWing算法基础课笔记——状态压缩DP:蒙德里安的梦想

状态压缩DP 状态是整数&#xff0c;但把它看成二进制数&#xff0c;二进制中每一位是0或1表示不同的情况。 蒙德里安的梦想 291. 蒙德里安的梦想 - AcWing题库 题目 求把 NM&#x1d441;&#x1d440; 的棋盘分割成若干个 1212 的长方形&#xff0c;有多少种方案。 例如…

Java面试题:聚簇索引和非聚簇索引

聚簇索引和非聚簇索引 聚簇索引(聚集索引) 将数据的存储和索引放在一块,索引结构的叶子节点保存了行数据 索引字段必须存在,且只能存在一个 非聚集索引(二级索引) 将数据和索引分开存储,索引结构的叶子节点关联的是对应的主键 索引字段可以存在多个 索引的选取规则 如果…

2024 年 8 款最佳建筑 3D 渲染软件

你现在使用的3D 渲染软件真得适合你吗&#xff1f; 在建筑和室内渲染当中&#xff0c;市面上有许多3D渲染软件可供选择。然而&#xff0c;并不是每款软件都适合你的需求。本指南将重点介绍2024年精选的8款最佳建筑3D渲染软件&#xff0c;帮助你了解不同的选项&#xff0c;并选…

第100+13步 ChatGPT学习:R实现决策树分类

基于R 4.2.2版本演示 一、写在前面 有不少大佬问做机器学习分类能不能用R语言&#xff0c;不想学Python咯。 答曰&#xff1a;可&#xff01;用GPT或者Kimi转一下就得了呗。 加上最近也没啥内容写了&#xff0c;就帮各位搬运一下吧。 二、R代码实现决策树分类 &#xff08;…

SSM宠物领养系统-计算机毕业设计源码08465

目 录 摘要 1 绪论 1.1课题背景及意义 1.2研究现状 1.3ssm框架介绍 1.3论文结构与章节安排 2 宠物领养系统系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 …

大模型管理平台:one-api使用指南

大模型相关目录 大模型&#xff0c;包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步&#xff0c;扬帆起航。 大模型应用向开发路径&#xff1a;AI代理工作流大模型应用开发实用开源项目汇总大模…

Go 实现SFTP连接服务

我们将SFTP连接和处理逻辑&#xff0c;以及登录账户信息封装&#xff0c;这样可以在不同的地方重用代码&#xff0c;并且可以轻松地更改登录凭据。下面我将演示如何使用Go语言中的结构体来封装这些信息&#xff0c;并实现一个简单的SFTP服务器&#xff1a; package mainimport…

信息系统项目管理师 | 新一代信息技术

关注WX&#xff1a;CodingTechWork 物联网 定义 The Internet of Things是指通过信息传感设备&#xff0c;按约定的协议&#xff0c;将任何物品与互联网连接&#xff0c;进行信息交互和通信&#xff0c;以实现智能化识别。定位、跟踪、监控和管理的一种网络。物联网主要解决…

采购OLED透明屏指南

一、引言 OLED透明屏作为一种前沿的显示技术&#xff0c;以其独特的透明度和出色的显示效果&#xff0c;受到了众多行业的青睐。在采购OLED透明屏时&#xff0c;需要综合考虑多个因素&#xff0c;以确保选择到符合需求的高质量产品。以下是一份详细的采购OLED透明屏指南&#x…

昇思25天学习打卡营第1天|基本介绍与快速入门

先贴上打卡截图 基本介绍 首先来看基本介绍&#xff0c;昇思MindSpore是华为的一个全场景深度学习框架&#xff0c;属于昇腾AI全栈的一部分。 总体架构如下图所示&#xff08;来自官方学习材料&#xff09; 从对底层多样性硬件适用的Runtime到应用层面的Model Zoo、科学计算…

首码项目对接app推广,寻找核心资源项目!

深度挖掘首码网&#xff08;www.shoumw.com&#xff09;项编码项目网站&#xff1a;帮助您轻松获取最新项目资源 在当下这个充满机会和挑战的创业氛围中&#xff0c;找到可信赖的项目资源已成为创业者们的主要任务。首码项目网是一家专注于首码项目发布和推广的平台&#xff0c…

Hi3861 OpenHarmony嵌入式应用入门--LiteOS MessageQueue

CMSIS 2.0接口中的消息&#xff08;Message&#xff09;功能主要涉及到实时操作系统&#xff08;RTOS&#xff09;中的线程间通信。在CMSIS 2.0标准中&#xff0c;消息通常是通过消息队列&#xff08;MessageQueue&#xff09;来进行处理的&#xff0c;以实现不同线程之间的信息…

Calibre - 合并电子书(EpubMerge)

这里使用 Calibre 软件和 EpubMerge 插件 EpubMerge github &#xff1a; https://github.com/JimmXinu/EpubMerge 1、安装 Merge 插件 安装后需要重启 calibre 2、查看设置 4 3、选中文件、开始合并 合并完成后&#xff0c;会弹窗窗口&#xff0c;来编辑 合辑的元信息 完成…

全网最强SpringMVC教程 | 万字长文爆肝SpringMVC(二)

SpringMVC_day02 今日内容 完成SSM的整合开发能够理解并实现统一结果封装与统一异常处理能够完成前后台功能整合开发掌握拦截器的编写 1&#xff0c;SSM整合 前面我们已经把Mybatis、Spring和SpringMVC三个框架进行了学习&#xff0c;今天主要的内容就是把这三个框架整合在一…