鸿蒙应用开发-初见:ArkUI

编程范式:命令式->声明式

以一个卡片的实现做下讲解

命令式

简单讲就是需要开发用代码一步一步进行布局,这个过程需要开发全程参与。

  • Objective-C
UIView *cardView = [[UIView alloc] init];
cardView.backgroundColor = [UIColor whiteColor];
cardView.layer.cornerRadius = 16;
cardView.clipsToBounds = YES;
[self.view addSubview:cardView];
[cardView mas_makeConstraints:^(MASConstraintMaker *make) {make.left.mas_equalTo(16);make.right.mas_offset(-16);make.height.mas_equalTo(116);make.top.mas_equalTo(100);
}];NSString *imgUrl = @"https://ke-image.ljcdn.com//110000-inspection//pc1_nBllrJgGj_1.jpg.280x210.jpg";
UIImageView *imgView = [[UIImageView alloc] init];
imgView.backgroundColor = [UIColor lightGrayColor];
[imgView sd_setImageWithURL:[NSURL URLWithString:imgUrl]];
[cardView addSubview:imgView];
[imgView mas_makeConstraints:^(MASConstraintMaker *make) {make.top.bottom.mas_offset(0);make.left.mas_equalTo(0);make.width.mas_equalTo(107);
}];UILabel *titleLbl = [[UILabel alloc] init];
titleLbl.font = [UIFont systemFontOfSize:14 weight:UIFontWeightBold];
titleLbl.textColor = [UIColor blackColor];
titleLbl.text = @"万柳书院新一区 南北向满五唯一";
[cardView addSubview:titleLbl];
[titleLbl mas_makeConstraints:^(MASConstraintMaker *make) {make.left.mas_equalTo(imgView.mas_right).mas_offset(12);make.right.mas_offset(-12);make.top.mas_equalTo(16);
}];UILabel *subTitleLbl = [[UILabel alloc] init];
subTitleLbl.textColor = [UIColor blackColor];
subTitleLbl.font = [UIFont systemFontOfSize:12 weight:UIFontWeightRegular];
subTitleLbl.text = @"4室2厅/278.35㎡/南 北/万柳书院";
[cardView addSubview:subTitleLbl];
[subTitleLbl mas_makeConstraints:^(MASConstraintMaker *make) {make.left.right.mas_equalTo(titleLbl);make.top.mas_equalTo(titleLbl.mas_bottom).mas_offset(8);
}];UILabel *priceLbl = [[UILabel alloc] init];
priceLbl.font = [UIFont systemFontOfSize:14 weight:UIFontWeightBold];
priceLbl.textColor = [UIColor redColor];
priceLbl.text = @"4238万";
[cardView addSubview:priceLbl];
[priceLbl mas_makeConstraints:^(MASConstraintMaker *make) {make.left.mas_equalTo(titleLbl);make.bottom.mas_offset(-16);
}];UILabel *avgPriceLbl = [[UILabel alloc] init];
avgPriceLbl.textColor = [UIColor lightGrayColor];
avgPriceLbl.font = [UIFont systemFontOfSize:12 weight:UIFontWeightRegular];
avgPriceLbl.text = @"155,445元/平";
[cardView addSubview:avgPriceLbl];
[avgPriceLbl mas_makeConstraints:^(MASConstraintMaker *make) {make.left.mas_equalTo(priceLbl.mas_right).mas_offset(2);make.right.mas_lessThanOrEqualTo(titleLbl.mas_right);make.bottom.mas_equalTo(priceLbl);
}];

声明式

声明式则是由开发使用语言描述UI页面长什么样子,之后全权交给引擎去做

  1. 对页面结构进行大的拆解。比如上面卡片分左右两大部分
  2. 选用合适的容器组件进行页面描述
  3. 针对拆解出来的每个部分重复上面的两步,直到无法拆解只能使用基本组件描述为止

比如上面的卡片可以进行如下的拆分

  1. 整体是一个Row容器,分为左右两大部分,左边是图片,右边是一个Column容器
  2. 右边Column容器又拆分为两大部分,上面是标题和描述,下面是价格。两部分按照space-between布局
  3. 上面的标题和描述作为一个整体,里面拆分成Column的两个组件
  4. 下面价格可以直接使用系统组件Text

ReactNative

<Viewstyle={{borderRadius: 8,marginHorizontal: 16,flexDirection: 'row',backgroundColor: 'white',overflow: 'hidden',height: 116,}}><Imagesource={{uri: 'https://ke-image.ljcdn.com//110000-inspection//pc1_nBllrJgGj_1.jpg.280x210.jpg',}}style={{width: 107, backgroundColor: '#eee'}}/><Viewstyle={{marginVertical: 16,marginHorizontal: 12,flex: 1,justifyContent: 'space-between',}}><View><Text style={{fontSize: 14, color: '#222', fontWeight: '500'}}>万柳书院新一区 南北向满五唯一</Text><Text style={{fontSize: 11, color: '#222', marginTop: 8}}>4室2厅/278.35㎡/南 北/万柳书院</Text></View><Viewstyle={{flexDirection: 'row', marginTop: 8, alignItems: 'flex-end'}}><Textstyle={{fontSize: 17,color: '#E62222',fontWeight: 'bold',}}>4238万</Text><Text style={{fontSize: 11, color: '#999', marginLeft: 6}}>155,445元/平</Text></View></View>
</View>

SwiftUI

HStack(spacing:0) {AsyncImage(url: URL(string: "https://ke-image.ljcdn.com//110000-inspection//pc1_nBllrJgGj_1.jpg.280x210.jpg")).frame(width:107).aspectRatio(contentMode: .fill).clipped()VStack(alignment: .leading,spacing:0) {VStack(alignment: .leading,spacing:0) {Text("万柳书院新一区 南北向满五唯一").lineLimit(1).font(.system(size: 14)).foregroundColor(.black).fontWeight(.bold)Text("4室2厅/278.35㎡/南 北/万柳书院").lineLimit(1).font(.system(size: 12)).foregroundColor(.black).padding(.top, 8)}Spacer()HStack(alignment: .bottom,spacing:2) {Text("4238万").font(.system(size: 14)).foregroundColor(.red).fontWeight(.bold)Text("155,445元/平").font(.system(size: 12)).foregroundColor(.secondary).padding(.leading, 2)}}.padding(.vertical, 16).padding(.horizontal, 12)Spacer()
}
.frame(height: 116)
.background(.white)
.clipShape(RoundedRectangle(cornerRadius: 8))
.padding(.horizontal, 16)
}

ArkUI

  Row() {Row() {Image("https://ke-image.ljcdn.com//110000-inspection//pc1_nBllrJgGj_1.jpg.280x210.jpg").width(107).height("100%").objectFit(ImageFit.Cover)Column() {Column() {Text("柳书院新一区 南北向满五唯一").fontSize(16).fontColor("#222").maxLines(1)Text("4室2厅/278.35㎡/南 北/万柳书院").fontSize(14).fontColor("#222").maxLines(1).margin({ top: 8 })}.alignItems(HorizontalAlign.Start)Row() {Text("4238万").fontSize(15).fontColor("#E62222").fontWeight(FontWeight.Bold)Text("155,445元/平").fontSize(13).fontColor("#222").margin({ left: 2 })}.justifyContent(FlexAlign.Start).alignItems(VerticalAlign.Bottom)}.width("100%").height("100%").padding({ top: 16, bottom: 16, left: 12, right: 12 }).alignItems(HorizontalAlign.Start).justifyContent(FlexAlign.SpaceBetween)}.borderRadius(8).margin({ left: 16, right: 16 }).backgroundColor(Color.White).justifyContent(FlexAlign.Start).clip(true)}.height(116).width("100%")

小结

  1. 从上面的例子可以看出来,声明式语法只需要我们描述UI长什么样就行。不需要做太多布局计算的工作,让我们少掉一些头发

  2. ArkUI和SwiftUI的语法最像,甚至它们的状态管理也很像,都是提供了状态绑定和监听机制来更新UI样式

声明式UI布局原理简述

Flutter中Widget的布局原理参考

Flutter中Widget的布局原理如下图所示。想了解更多Flutter的布局原理可以查看 深入理解 Flutter 布局约束

SwiftUI中的View布局原理参考

SwiftUI中的布局原理可以参考下图。想了解细节,可参考 SwiftUI 中布局的工作原理

小结

声明式布局想要布局子视图都会经历由上到下的一个过程,只有知道了子视图的大小之后才能根据对齐方式将子视图放置在准确的位置。

声明式布局几乎都是下面这个套路

  1. 父视图给子视图一个布局约束(作为Root的根视图默认是充满屏幕的,它给子视图的约束就是屏幕大小)
  2. 子视图渲染并将自身大小返回给父视图
  3. 父视图根据子视图的大小和设定的对齐方式计算要放置的位置
  4. 子视图的布局也遵循以上三步进行递归。整个过程是深度优先的

ArkUI

ArkUI官方链接

方舟开发框架(简称ArkUI)是鸿蒙开发的UI框架,提供如下两种开发范式,我们 只学声明式开发范式

  1. 基于ArkTS的声明式开发范式
  2. 兼容JS的类Web开发范式

整体架构图

我们使用ArkTS写完页面描述后,交给语言运行时进行语法解析,再之后由C++编写的后端引擎将UI转换为渲染指令交给渲染引擎绘制到屏幕上

ArkUI语法初见

  1. ArkTS对TypeScript语言进行扩展,提供值类型结构struct。
  2. struct定义自定义组件,必须搭配Component或者CustomDialog使用
  3. ArkUI中组件定义和状态管理都是通过装饰器来做的。TS中的装饰器主要有类装饰器、属性装饰器、方法装饰器以及参数装饰器四种
  4. 事件方法和属性方法只是方法的入参不一样,一个是基本值或者表达式值,一个是函数。
  5. 在TS中函数我们就把函数当成变量来用就行,只不过普通变量是存储一个类型的值,而函数用来存储一个输入到输出的转变过程
  6. 还记得我们上面说的描述UI嘛,在这里就在build函数中描述。框架会自动调用build,不需要我们手动调用

从代码到UI显示的整体渲染流程

ArkUI的渲染分为两大情况

从创建到显示(①~⑤)

① 通过devEco将源码编译成带类型标识的字节码文件,同时携带创建这个结构所需信息的指令流

② 通过跨语言调用生成C++层的Component树。这一步只是把ArkTS描述转变成了使用C++描述

③ 通过Component树生成Element树,Element是Component的实例,用于表示一个具体的组件节点。界面在运行时的树形结构就是通过Element树来维持的,同时自动更新的diff算法也是依赖Element树来减少复杂度的

④ 对于每个可显示的Element都会为其创建对应的RenderNode。RenderNode负责一个节点的显示信息,它形成的Render树维护着整个界面渲染需要用到的信息,包括位置、大小、绘制命令等。后续的布局、绘制都是在Render树上进行的

⑤ 实现真正的渲染并显示绘制结果

按钮点击到更新显示(⑥~⑪)

⑥ 点击事件传递到组件,组件的onClick事件方法被触发执行

⑦ 由于onClick事件方法中@State注解过的变量改变了,相应getter/setter函数会被触发

⑧ 状态管理模块定位出关联的UI组件

⑨ 状态管理模块更新相应的Element树的信息

⑩ 更新相应的UI组件的渲染信息

⑪ 界面显示,与⑤类似

盒子模型

上面我们说的布局原理,子视图上报给父视图自身大小的值是指 组件内容区的大小

ArkUI中常用布局容器

如何选择使用哪种布局

线性布局(Row/Column)

  1. 线性布局的子元素在线性方向上(水平方向和垂直方向)依次排列
  2. 线性布局容器包括 Row] 和 Column 。Column容器内子元素按照垂直方向排列,Row容器内子元素按照水平方向排列
主轴
  1. 线性布局容器在布局方向上的轴线,子元素默认沿主轴排列。
  2. Row容器主轴为横向,Column容器主轴为纵向。通过justifyContent属性设置子元素在容器主轴上的排列方式
  3. 默认相邻子元素是紧贴着的,也可以通过space设置子元素间的间距
Column容器内子元素在主轴上的排列

主轴方向:垂直向下

Column() {
...
}.justifyContent(FlexAlign.Start)

  1. justifyContent(FlexAlign.Start):元素在主轴方向首端对齐,第一个元素与行首对齐,同时后续的元素与前一个对齐
  2. justifyContent(FlexAlign.Center):元素在主轴方向中心对齐,第一个元素与行首的距离与最后一个元素与行尾距离相同
  3. justifyContent(FlexAlign.End):元素在主轴方向尾部对齐,最后一个元素与行尾对齐,其他元素与后一个对齐
  4. justifyContent(FlexAlign.Spacebetween):主轴方向均匀分配元素,相邻元素之间距离相同。第一个元素与行首对齐,最后一个元素与行尾对齐
  5. justifyContent(FlexAlign.SpaceAround):主轴方向均匀分配元素,相邻元素之间距离相同。第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半
  6. justifyContent(FlexAlign.SpaceEvenly):主轴方向均匀分配元素,相邻元素之间的距离、第一个元素与行首的间距、最后一个元素到行尾的间距都完全一样
Row容器内子元素在主轴上的排列

主轴方向:水平向右

Row() {
...
}.justifyContent(FlexAlign.Start)

  1. justifyContent(FlexAlign.Start):元素在主轴方向首端对齐,第一个元素与行首对齐,同时后续的元素与前一个对齐
  2. justifyContent(FlexAlign.Center):元素在主轴方向中心对齐,第一个元素与行首的距离与最后一个元素与行尾距离相同
  3. justifyContent(FlexAlign.End):元素在主轴方向尾部对齐,最后一个元素与行尾对齐,其他元素与后一个对齐
  4. justifyContent(FlexAlign.Spacebetween):主轴方向均匀分配元素,相邻元素之间距离相同。第一个元素与行首对齐,最后一个元素与行尾对齐
  5. justifyContent(FlexAlign.SpaceAround):主轴方向均匀分配元素,相邻元素之间距离相同。第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半
  6. justifyContent(FlexAlign.SpaceEvenly):主轴方向均匀分配元素,相邻元素之间的距离、第一个元素与行首的间距、最后一个元素到行尾的间距都完全一样
交叉轴
  1. 垂直于主轴方向的轴线。Row容器交叉轴为纵向,Column容器交叉轴为横向。
  2. 通过alignItems属性设置子元素在交叉轴(排列方向的垂直方向)上的对齐方式
  3. alignSelf属性用于控制单个子元素在容器交叉轴上的对齐方式,其优先级高于alignItems属性,如果设置了alignSelf属性,则在单个子元素上会覆盖alignItems属性
Column容器内子元素在水平方向上的排列
Column() {
...
}.alignItems(HorizontalAlign.Start)

  1. HorizontalAlign.Start:子元素在水平方向左对齐
  2. HorizontalAlign.Center:子元素在水平方向居中对齐
  3. HorizontalAlign.End:子元素在水平方向右对齐。
Row容器内子元素在垂直方向上的排列
Row() {
...
}.alignItems(VerticalAlign.Top)

  1. VerticalAlign.Top:子元素在垂直方向顶部对齐
  2. VerticalAlign.Center:子元素在垂直方向居中对齐
  3. VerticalAlign.Bottom:子元素在垂直方向底部对齐

层叠布局(Stack)

  1. 层叠布局主要用于实现基于Z轴的布局,容器中的子元素(子组件)依次入栈,后一个子元素覆盖前一个子元素,子元素可以叠加,也可以通过zIndex设置位置
  2. 可以通过 alignContent参数 实现位置的相对移动
Stack({ alignContent: Alignment.BottomStart })

弹性布局(Flex)

  1. Row和Column容器只支持单方向的布局。你可以把Flex理解为它俩的升级版,能更灵活的控制布局方向和子元素布局。
  2. 可以设置布局方向,是否自动换行等
弹性布局方向图

Flex({ direction: FlexDirection.Row })

  1. FlexDirection.Row(默认值):主轴为水平方向,子组件从起始端沿着水平方向开始排布
  2. FlexDirection.RowReverse:主轴为水平方向,子组件从终点端沿着FlexDirection. Row相反的方向开始排布
  3. FlexDirection.Column:主轴为垂直方向,子组件从起始端沿着垂直方向开始排布
  4. FlexDirection.ColumnReverse:主轴为垂直方向,子组件从终点端沿着FlexDirection. Column相反的方向开始排布

主轴为水平方向的Flex容器示意图

主轴对齐方式

通过justifyContent参数设置在主轴方向的对齐方式,和Row、Column的主轴对齐方式行为一样

交叉轴对齐方式

可以通过Flex组件的alignItems参数设置子组件在交叉轴的对齐方式,子组件默认使用Flex组件的对齐方式。但也可以通过alignSelf单独设置对齐方式

Flex({ alignItems: ItemAlign.Start })

ItemAlign.Auto:使用Flex容器中默认配置。

ItemAlign.Start:交叉轴方向首部对齐

ItemAlign.Center:交叉轴方向居中对齐

ItemAlign.End:交叉轴方向底部对齐

子组件通过 alignSelf 设置在父容器交叉轴的对齐格式,覆盖Flex布局容器中alignItems配置

相对布局(RelativeContainer)

  1. 相对布局可以让子元素指定兄弟元素或父容器作为锚点,基于锚点做位置布局
  2. 必须为RelativeContainer及其子元素设置ID,用于指定锚点信息。未设置ID的子元素不会显示
  3. RelativeContainer ID为“container”,其余子元素的ID通过id属性设置。
  4. 子元素通过 alignRules 指定相对布局规则

锚点的对齐位置示意图

一个示例

@Entry
@Component
struct Index {build() {Row() {RelativeContainer() {Row().width(100).height(100).backgroundColor('#FF3333').alignRules({top: { anchor: '__container__', align: VerticalAlign.Top },  //以父容器为锚点,竖直方向顶头对齐middle: { anchor: '__container__', align: HorizontalAlign.Center }  //以父容器为锚点,水平方向居中对齐}).id('row1')  //设置锚点为row1Row() {Image($r('app.media.icon'))}.height(100).width(100).alignRules({top: { anchor: 'row1', align: VerticalAlign.Bottom },  //以row1组件为锚点,竖直方向低端对齐left: { anchor: 'row1', align: HorizontalAlign.Start }  //以row1组件为锚点,水平方向开头对齐}).id('row2')  //设置锚点为row2Row().width(100).height(100).backgroundColor('#FFCC00').alignRules({top: { anchor: 'row2', align: VerticalAlign.Top }}).id('row3')  //设置锚点为row3Row().width(100).height(100).backgroundColor('#FF9966').alignRules({top: { anchor: 'row2', align: VerticalAlign.Top },left: { anchor: 'row2', align: HorizontalAlign.End },}).id('row4')  //设置锚点为row4Row().width(100).height(100).backgroundColor('#FF66FF').alignRules({top: { anchor: 'row2', align: VerticalAlign.Bottom },middle: { anchor: 'row2', align: HorizontalAlign.Center }}).id('row5')  //设置锚点为row5}.width(300).height(300).border({ width: 2, color: '#6699FF' })}.height('100%').margin({ left: 30 })}
}

创建列表(List)

  1. 列表容器是为了高效处理长列表的容器,能支持横向、竖向滚动,数据分组,分组头悬浮等功能
  2. 列表容器内的所有子元素必须是 ListItemGroup 或ListItem,我们实际的内容是在这俩容器内部的
  3. 创建列表子元素一般使用 ForEach 来减少开发量
List、ListItemGroup和ListItem组件关系

List() {ListItem() {}ListItem() {}ListItemGroup() {}LazyForEach(this.dataSource, item => {ListItem() {...}})
}
// 设置垂直方向
.listDirection(Axis.Vertical)
// 粘性header
.sticky(StickyStyle.Header)
// 两列
.lanes(2)

创建网格(Grid/GridItem)

  1. 网格布局主要用于处理固定行列的UI,也支持动态调整。很类似iOS中的UICollectionView。
  2. Grid 容器的子组件一定是 GridItem
Grid,GridItem关系

容器内每一个条目对应一个GridItem组件

行列数量可配
  1. Grid组件提供了rowsTemplate和columnsTemplate属性用于设置网格布局行列数量与尺寸占比。
  2. rowsTemplate和columnsTemplate属性值是一个由多个空格和’数字+fr’间隔拼接的字符串,fr的个数即网格布局的行或列数,fr前面的数值大小,用于计算该行或列在网格布局宽度上的占比,最终决定该行或列的宽度
Grid() {
...
}
.rowsTemplate('1fr 1fr 1fr')
.columnsTemplate('1fr 2fr 1fr')

单个网格可以横跨多行或多列

通过设置GridItem的rowStart、rowEnd、columnStart和columnEnd可以实现单个网格横跨多行或多列的场景

Grid() {GridItem() {}GridItem() {}GridItem() {}.columnStart(1).columnEnd(2)GridItem() {}.rowStart(1).rowEnd(2)GridItem() {}GridItem() {}GridItem() {}GridItem() {}.columnStart(1).columnEnd(3)
}
.rowsTemplate('1fr 1fr 1fr')
.columnsTemplate('1fr 1fr 1fr 1fr')
.columnsGap(8)
.rowsGap(8)

其他常用布局容器和组件

  • 创建轮播(Swiper)实现轮播图功能

  • 栅格布局(GridRow/GridCol)和Grid布局类似,但是可以根据设置的分割点动态显示列数。特别适合做多设备适配布局

  • Badge 实现消息小红点和消息数功能

  • WaterFlow 实现瀑布流功能

  • Video 实现视频播放功能

  • TextTimer 实现倒计时显示功能

  • DataPanel 数据面板组件,使用占比图展示多个数据的占比情况

  • Gauge 以环形图表形式展示数据

  • Marquee 走马灯效果

  • PatternLock 图形密码锁组件

  • Rating 评分组件

  • Stepper 步骤导航器组件,主要用于引导介绍功能

为了能让大家更好的学习鸿蒙 (Harmony OS) 开发技术,这边特意整理了《鸿蒙 (Harmony OS)开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙 (Harmony OS)开发学习手册》

入门必看:https://qr21.cn/FV7h05

  1. 应用开发导读(ArkTS)
  2. 应用开发导读(Java)

HarmonyOS 概念:https://qr21.cn/FV7h05

  1. 系统定义
  2. 技术架构
  3. 技术特性
  4. 系统安全

如何快速入门:https://qr21.cn/FV7h05

  1. 基本概念
  2. 构建第一个ArkTS应用
  3. 构建第一个JS应用
  4. ……

开发基础知识:https://qr21.cn/FV7h05

  1. 应用基础知识
  2. 配置文件
  3. 应用数据管理
  4. 应用安全管理
  5. 应用隐私保护
  6. 三方应用调用管控机制
  7. 资源分类与访问
  8. 学习ArkTS语言
  9. ……

基于ArkTS 开发:https://qr21.cn/FV7h05

  1. Ability开发
  2. UI开发
  3. 公共事件与通知
  4. 窗口管理
  5. 媒体
  6. 安全
  7. 网络与链接
  8. 电话服务
  9. 数据管理
  10. 后台任务(Background Task)管理
  11. 设备管理
  12. 设备使用信息统计
  13. DFX
  14. 国际化开发
  15. 折叠屏系列
  16. ……

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

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

相关文章

Qt_一个由单例引发的崩溃

Qt_一个由单例引发的崩溃 文章目录 Qt_一个由单例引发的崩溃摘要关于 Q_GLOBAL_STATIC代码测试布局管理器源码分析Demo 验证关于布局管理器析构Qt 类声明周期探索更新代码获取父类分析Qt 单例宏源码 关键字&#xff1a; Qt、 Q_GLOBAL_STATIC、 单例、 UI、 崩溃 摘要 今…

R语言实操记录——R包无法安装,报错:Warning in system(cmd) : ‘make‘ not found

R语言 R语言实操记录——R包无法安装&#xff0c;报错&#xff1a;Warning in system(cmd) : ‘make‘ not found 文章目录 R语言一、起因二、具体步骤2.1、确认问题源2.2、安装RTools2.3、与R(/Rstudio)绑定2.4、验证可行性 三、疑惑 一、起因 R语言在包的安装上是真的方便&…

西北大学计算机844考研-23年计网计算题详细解析

西北大学计算机844考研-23年计网计算题详细解析 1.计算无传输差错状态下停止—等待ARQ协议效率,电磁波传播速率为2*10^8m/s&#xff0c;链路长为2000m&#xff0c;帧长度为1000比特&#xff0c;计算传输速率10kbps及10Mbps时的协议效率&#xff08;即信道利用率&#xff09; …

中低压MOSFET 2N7002KW 60V 300mA 双N通道 SOT-323封装

2N7002KW小电流双N通道MOSFET&#xff0c;电压60V电流300mA&#xff0c;采用SOT-323封装形式。超高密度电池设计&#xff0c;适用于极低的ros (on)&#xff0c;具有导通电阻和最大直流电流能力&#xff0c;ESD保护。可应用于笔记本中的电源管理&#xff0c;电池供电系统等产品应…

外观设计模式

package com.jmj.pattern.facade;public class Light {public void on(){System.out.println("打开电灯...");}public void off(){System.out.println("关闭电灯...");} }package com.jmj.pattern.facade;public class AirCondition {public void on(){S…

R语言阶段复习一

创建一个长度为7的字符向量&#xff0c;元素为"A", "B", "C", "D", "E", "F", "G"&#xff0c;并命名为vec1。 创建一个因子&#xff0c;包含6个水果&#xff1a;"apple", "banana"…

stack和queue

目录 1.什么是stack 2.容器适配器 3.stack的使用 top push pop 4.模拟实现stack 1.什么是stack 1. stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行 元素的插入与提取操作。(后进先出) 2. stack是作为容…

C语言:一个数如果恰好等于除它本身外的因子之和,这个数就称为完数。例如6=1+2+3。编程找出1000以内的所有完数。

分析&#xff1a; 在主函数 main 中&#xff0c;程序首先定义三个整型变量 m、s 和 i&#xff0c;并用于计算和判断完数。然后使用 printf 函数输出提示信息。 接下来&#xff0c;程序使用 for 循环结构&#xff0c;从 2 到 999 遍历所有的数。对于每个遍历到的数 m&#xff0c…

如何通过nginx进行反向代理

简单介绍 正向代理 正向代理服务器是一个位于客户端和原始服务器(origin server)之间的服务器&#xff0c;为了能够从原始服务器取得内容&#xff0c;客户端向代理发送一个请求并指定目标(原始服务器)&#xff0c;然后代理向原始服务器转交请求并将获得的内容返回给客户端。正向…

Ubuntu+Tesla V100环境配置

系统基本信息 nvidia-smi’ nvidia-smi 470.182.03 driver version:470.182.03 cuda version: 11.4 查看系统体系结构 uname -aUTC 2023 x86_64 x86_64 x86_64 GNU/Linux 下载miniconda https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/?CM&OA https://mi…

redis报错3

INFO: Initializing SpringDispatcherServletdispatcherServlet

OpenCV快速入门:移动物体检测和目标跟踪

文章目录 前言一、移动物体检测和目标跟踪简介1.1 移动物体检测的基本概念1.2 移动物体检测算法的类型1.3 目标跟踪的基本概念1.4 目标跟踪算法的类型 二、差值法检测移动物体2.1 差值法原理2.2 差值法公式2.3 代码实现2.3.1 视频或摄像头检测移动物体2.3.2 随机动画生成的移动…

串口数据包收发的思路和流程-stm32入门

本节主要内容&#xff1a; 如何去规定一个合理的数据包格式如何收发数据包 1. 数据包格式规定/定义 1.1 HEX 数据包定义 固定包长&#xff0c;含包头包尾 可变包长&#xff0c;含包头包尾 首先数据包的作用是把一个个单独的数据给打包起来&#xff0c;方便我们进行多字节…

Java LeetCode篇-深入了解关于数组的经典解法

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 轮转数组 1.1 使用移位的方式 1.2 使用三次数组逆转法 2.0 消失的数字 2.1 使用相减法 2.2 使用异或的方式 3.0 合并两个有序数组 3.1 使用三指针方式 3.2 使用合…

Spring Cache(缓存框架)

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

vue 中 js 金额数字转中文

参考&#xff1a;js工具函数之数字转为中文数字和大写金额_js封装工具类函数金额大写-CSDN博客 我使用的框架vol.core。 客户需求要将录入框的金额数字转换成中文在旁边显示&#xff0c;换了几种函数&#xff0c;最终确定如下函数 function changeToChineseMoney(Num) {//判断…

Android Termux SFTP如何实现远程文件传输

文章目录 1. 安装openSSH2. 安装cpolar3. 远程SFTP连接配置4. 远程SFTP访问4. 配置固定远程连接地址 SFTP&#xff08;SSH File Transfer Protocol&#xff09;是一种基于SSH&#xff08;Secure Shell&#xff09;安全协议的文件传输协议。与FTP协议相比&#xff0c;SFTP使用了…

【24届校招】c++选手还有机会吗?如何选择更好的出路?

一、今年为什么c选手就业形势如此艰难&#xff1f; 去年c岗位的火热&#xff0c;不少c选手拿到高薪offer&#xff0c;今年转c的人群变多&#xff0c;内卷加剧&#xff0c;高学历大佬多如牛毛&#xff0c;很多比较好的c岗位多人投递&#xff0c;僧多肉少。 从行情来说&#xf…

Selenium-Unittest单元测试框架

1、Unittest介绍 为什么要学习单元测试框架 测试用例的组织与运行需要单元测试框架的参与&#xff0c;从而满足不同测试场景的需要&#xff0c;单元测试框架提供了丰富的比较方法&#xff1a;实际结果与预期结果的对比测试结果 单元测试框架提供了丰富的日志&#xff1a;给出测…

livox 半固体激光雷达 gazebo 仿真 | 安装与验证

livox 半固体激光雷达 gazebo 仿真 | 安装与验证 livox 半固体激光雷达 gazebo 仿真 | 安装与验证livox 介绍安装验证 livox 半固体激光雷达 gazebo 仿真 | 安装与验证 livox 介绍 览沃科技有限公司&#xff08;Livox&#xff09;成立于2016年。为了革新激光雷达行业&#xf…