鸿蒙ArkUI:【编程范式:命令式->声明式】

电子说

1.3w人已加入

描述

命令式

简单讲就是需要开发用代码一步一步进行布局,这个过程需要开发全程参与。
开发前请熟悉鸿蒙开发指导文档:[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md]

  • Objective-C
ObjectiveC
复制代码
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

TypeScript
复制代码
 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 >

Flutter

flutter
复制代码

SwiftUI

swift
复制代码
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

typescript
复制代码
  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%")
  
`HarmonyOS与OpenHarmony鸿蒙文档籽料:mau123789是v直接拿`

鸿蒙

小结

  1. 从上面的例子可以看出来,声明式语法只需要我们描述UI长什么样就行。不需要做太多布局计算的工作,让我们少掉一些头发
  2. ArkUI和SwiftUI的语法最像,甚至它们的状态管理也很像,都是提供了状态绑定和监听机制来更新UI样式

审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分