鸿蒙应用开发-初见:ArkUI

news2024/11/25 12:44:21

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

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

命令式

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

  • 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

<View
  style={{
    borderRadius: 8,
    marginHorizontal: 16,
    flexDirection: 'row',
    backgroundColor: 'white',
    overflow: 'hidden',
    height: 116,
  }}>
  <Image
    source={{
      uri: 'https://ke-image.ljcdn.com//110000-inspection//pc1_nBllrJgGj_1.jpg.280x210.jpg',
    }}
    style={{width: 107, backgroundColor: '#eee'}}
  />
  <View
    style={{
      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>
    <View
      style={{flexDirection: 'row', marginTop: 8, alignItems: 'flex-end'}}>
      <Text
        style={{
          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')  //设置锚点为row1

        Row() {
          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')  //设置锚点为row2

        Row()
          .width(100)
          .height(100)
          .backgroundColor('#FFCC00')
          .alignRules({
            top: { anchor: 'row2', align: VerticalAlign.Top }
          })
          .id('row3')  //设置锚点为row3

        Row()
          .width(100)
          .height(100)
          .backgroundColor('#FF9966')
          .alignRules({
            top: { anchor: 'row2', align: VerticalAlign.Top },
            left: { anchor: 'row2', align: HorizontalAlign.End },
          })
          .id('row4')  //设置锚点为row4

        Row()
          .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.coloradmin.cn/o/1260395.html

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

相关文章

文生视频的发展史及其原理解析:从Gen2、Emu Video到SVD、PixelDance

前言 考虑到文生视频开始爆发&#xff0c;比如 今年&#xff0c;作为最早探索视频生成领域的领头羊之一&#xff0c;Runway 先后发布Gen-1、Gen-2 模型(runway也是Stable Diffusion 开发商之一)&#xff0c;特别是Gen-2带来了电影级别的高清晰度&#xff0c;令人瞩目&#xf…

Vue3-pnpm包管理器创建项目

一些优势&#xff1a;比同类工具快2倍左右、节省磁盘空间 官网&#xff1a;pnpm - 速度快、节省磁盘空间的软件包管理器 | pnpm中文文档 | pnpm中文网 npm升级到yarn再升级到pnpm&#xff08;速度更快&#xff09; 安装方式&#xff1a;npm install -g pnpm 创建项目&#…

C++之常用的拷贝和替换算法

C之常用的拷贝和替换算法 copy #include<iostream> using namespace std; #include<vector> #include<algorithm>void Myptint(int val) {cout << val << " "; }void test() {vector<int> v;for (int i 0; i < 10; i){v.pus…

波奇学C++:C++11的新特性

列表初始化 #include<iostream> using namespace std; struct A {int _x;int _y; }; int main() {// 三种方式等价&#xff0c;并且可以省略int x 1;int y { 2 };int z{ 3 };return 0; } {}按声明顺序初始化类成员变量 A p{ 1,2 }; cout << p._x; //1 cout &…

数字化转型导师坚鹏:BLM保险公司数字化转型战略培训圆满结束

在数字化转型背景下&#xff0c;为了落实监管政策《关于保险公司业保险业数字化转型的指导意见》&#xff0c;充分认识到学习保险公司数字化转型战略的价值和重要性&#xff0c;特别举办《2023年保险公司数字化转型战略专题培训班》。为了改变大家的认知&#xff0c;为了拓宽大…

销售漏斗是什么?

销售漏斗是一个重要的销售管理工具&#xff0c;它可以帮助销售人员更好地管理和跟踪潜在客户。销售漏斗模型通常被广泛应用于B2B销售中&#xff0c;它可以将销售过程细分为多个阶段&#xff0c;例如潜在客户、初步沟通、方案报价、谈判和签约等。 销售漏斗有以下作用&#xff…

洗地机应该怎么选?希亦、必胜、米博、添可、小米洗地机实测推荐

作为一个常年测评智能家居的博主&#xff0c;关于洗地机的测评使用这些年也积累了不少的体验感受。以至于常被周边的朋友问到&#xff0c;洗地机到底是不是真的好用&#xff1f;洗地机有什么优点吗&#xff1f;选购的时候应该怎么选呢&#xff1f;洗地机什么牌子比较好呢&#…

Spring Data Redis切换底层Jedis 和 Lettuce实现

1 简介 Spring Data Redis是 Spring Data 系列的一部分&#xff0c;它提供了Spring应用程序对Redis的轻松配置和使用。它不仅提供了对Redis操作的高级抽象&#xff0c;还支持Jedis和Lettuce两种连接方式。 可通过简单的配置就能连接Redis&#xff0c;并且可以切换Jedis和Lett…

redis优化秒杀和消息队列

redis优化秒杀 1. 异步秒杀思路1.1 在redis存入库存和订单信息1.2 具体流程图 2. 实现2.1 总结 3. Redis的消息队列3.1 基于list实现消息队列3.2 基于PubSub实现消息队列3.3 基于stream实现消息队列3.3.1 stream的单消费模式3.3.2 stream的消费者组模式 3.4 基于stream消息队列…

解决方案:新版WPS-右键粘贴值到可见单元格没有了

旧版WPS&#xff0c;右键就能出现 但是新版WPS不是在这里&#xff08;方法1&#xff09; 新版WPS&#xff08;方法2&#xff09; 视频详细教程链接&#xff1a;解决方案&#xff1a;新版WPS-右键粘贴值到可见单元格没有了 -- 筛选后复制公式粘贴为数值_哔哩哔哩_bilibili

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之Linux 进程管理 5》(9)

《Linux操作系统原理分析之Linux 进程管理 5》&#xff08;9&#xff09; 4 Linux 进程管理4.5 Linux 信号4.5.1 信号的作用和种类1.信号机制2.信号种类 4.5.2 信号的处理4.5.3 信号处理函数1&#xff0e;数据结构2&#xff0e; 处理函数 signal3&#xff0e;程序例 4 Linux 进…

【特斯拉 tesla Roadster 开源 地址】

下载地址 https://service.tesla.com/roadster 打开长这样&#xff0c;在右边就是目前公开的东西了 服务信息 服务手册 零件手册 &#xff08;EPC&#xff09; 电路 连接 工作原理&#xff1a;敞篷跑车 https://service.tesla.com/docs/Public/Roadster/TheoryOp/1.2.5/tabm…

在Linux中部署MeterSphere并且结合内网穿透实现远程访问本地管理页面——“cpolar内网穿透”

文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 前言 MeterSphere 是一站式开源持续测试平台, 涵盖测试跟踪、接口测试、UI 测试和性能测试等功能&am…

Apache Doris 整合 FLINK 、 Hudi 构建湖仓一体的联邦查询入门

1.概览 多源数据目录&#xff08;Multi-Catalog&#xff09;功能&#xff0c;旨在能够更方便对接外部数据目录&#xff0c;以增强Doris的数据湖分析和联邦数据查询能力。 在之前的 Doris 版本中&#xff0c;用户数据只有两个层级&#xff1a;Database 和 Table。当我们需要连…

无需API开发,商米云打印机集成营销系统,优化电商运营和订单处理速度

轻松实现商米云打印机连接 在电子商务和客户服务系统运营中&#xff0c;能够无缝地连接硬件设备&#xff0c;如打印机&#xff0c;至关重要。商米云打印机为电商和客服系统提供了一种无需复杂API开发的连接方式。通过简化的配置流程&#xff0c;商家可以轻松地将商米云打印机集…

【深度学习】概率图模型(二)有向图模型详解(条件独立性、局部马尔可夫性及其证明)

文章目录 一、有向图模型1. 贝叶斯网络的定义2. 条件独立性及其证明a. 间接因果关系 X 3 → X 2 → X 1 X_3 \rightarrow X_2 \rightarrow X_1 X3​→X2​→X1​b. 间接果因关系 X 1 → X 2 → X 3 X_1 \rightarrow X_2 \rightarrow X_3 X1​→X2​→X3​c. 共因关系 X 1 ← X…

动态网页从数据库取信息,然后展示。

把数据库的驱动放在bin目录下。 通过servlet 读取数据库的内容&#xff0c;生成session,然后跨页面传给展示页。 package src;import java.io.IOException; import java.io.PrintWriter; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSe…

Git的原理与使用(一):Git的基本操作(包含:版本回退)

Git原理与使用一 一.Git的初识与安装1.什么是Git2.如何安装Git1.git命令与git help(Git下的"man手册")2.centos下安装Git3.ubantu下安装Git 二.Git的前置操作与前置知识1.创建Git本地仓库2.配置Git3.理解Git的分区1.工作区2.暂存区3.版本库4.分区关系总结 三.添加文件…

Open Feign 源码解析(四) --- 请求对象构造(上)

Open Feign 源码解析四 请求对象的构造&#xff08;上&#xff09; 源码前三篇文章写了这个图的过程 源码前三篇文章的内容归纳起来就是讲了这样的问题&#xff1a; 如何把接口转换为具有发送http请求能力的feign client对象以及如何整合到Spring容器中&#xff1f; 如何构造…

【华为OD题库-040】计算最接近的数-java

题目 给定一个数组X和正整数K&#xff0c;请找出使表达式X[i]-x[i1]…-X[ik-1]&#xff0c;结果最接近于数组中位数的下标i&#xff0c;如果有多个满足条件&#xff0c;请返回最大的i。 其中&#xff0c;数组中位数:长度为N的数组&#xff0c;按照元素的值大小升序排列后&#…