鸿蒙开发,简单入门一下。

前言

据说鸿蒙Next,要抛弃Android了,加上最近面试,老是被人问到会鸿蒙吗,所以花了点时间,来学习鸿蒙开发。经过几天的时间学习,自己也根据WanAndroid API写了个APP,感兴趣可以去看下,项目地址我贴到文章最后。
本文是基于 Harmony OS Api 9/ DevEco Studio 3.1.1 Release开发。

基本概念

我们打开鸿蒙开发官网,可以发现,HarmonyOS提供了一套UI开发框架,即方舟开发框架(ArkUI框架)。ArkUI框架不同目的和技术背景的开发者提供了两种开发范式,分别是基于ArkTS的声明式开发范式(简称“声明式开发范式”)和兼容JS的类Web开发范式(简称“类Web开发范式”)。以下是两种开发范式对比:

ArkUI框架对比.png

作为客户端开发的我们,自然选择声明式开发范式(ArkTS语言)。此外鸿蒙还有两种应用模型,我们选择推荐的Stage模型

常见组件

Talk is cheap,show me code,本文将介绍几个常见组件,带你熟悉鸿蒙开发。

Hello Word

我们学习任何开发语言,大都是从Hello World开始的,本文也不例外。

@Entry
@Component
struct HelloWorld {
  @State message: string = 'Hello World'

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')
  }
}

预览效果:
在这里插入图片描述

实际就是通过一个垂直布局,实现了一个从上到下,一个文本控件+按钮,可以看到,鸿蒙开发的控件宽高使用的是百分比。

登陆界面

Hello World写完了,咱们来实现一个简单的登陆界面。

@Entry
@Component
struct Login {
  @State userName: string = 'admin'
  @State password: string = '123456'

  build() {
    Column() {

      Image($r('app.media.android_fly'))
        .width(75)
        .height(75)
        .margin({ top: 90 })

      Text('登陆界面')
        .fontSize(20)
        .fontWeight(700)
        .margin({ top: 12 })

      Text('登陆账号以使用更多服务')
        .fontSize(14)
        .fontColor('#999')
        .margin({ top: 6 })

      TextInput(
        {
          placeholder: '请输入用户名'
        }
      ).margin({ top: 30 })
        .onChange((value) => {
          this.userName = value
        })

      TextInput(
        {
          placeholder: '请输入密码'
        }
      ).margin({ top: 30 })
        .type(InputType.Password)
        .onChange((value) => {
          this.password = value
        })

      Button('登陆')
        .width('80%')
        .margin({ top: 30 })
        .onClick(() => {
          if (this.userName == 'admin' && this.password == '123456') {
            router.push({
              url: 'pages/Index'
            })
          } else {
            promptAction.showToast({
              message:'请输入正确的用户名密码'
            })
          }
        })

      Text('注册账号')
        .fontColor('#0078fd')
        .margin({ top: 15 })


    }.width('100%')
    .height('100%')
    .padding(10)
  }
}

这里着重要介绍一下TextInput,onChange接收输入框文字变化,类似Jetpack Compose TextField onValueChange

// EditText
TextField(
    value = "",
    onValueChange = {},
    placeholder = {
        Text(text = "Type something here")
    },
    colors = TextFieldDefaults.textFieldColors(
        containerColor = Color.White
    )
)

预览效果:
login

Banner

我们在做android开发,经常在首页会写一个广告轮播组件,鸿蒙直接提供了一个基础组件
Swiper。

@Entry
@Component
struct Banner {
  private control: SwiperController = new SwiperController()

  build() {
    Row() {
      Column() {
        Swiper(this.control) {
          Image($r('app.media.ic_my_respect')).imgStyle()
          Image($r('app.media.ic_my_examine_fail')).imgStyle()
          Image($r('app.media.ic_my_custom_service')).imgStyle()
          Image($r('app.media.ic_my_feedback')).imgStyle()
        }
        .padding(10)
        .loop(true)
        .autoPlay(true)
        .interval(2000)
        // .vertical(true) //纵向轮播

        Row() {
          Button('上一页')
            .onClick(() => {
              this.control.showPrevious()
            })

          Button('下一页').onClick(() => {
            this.control.showNext()
          }).margin({ left: 10 })
        }

      }

    }

  }
}

预览效果:
banner

Flex

弹性布局(Flex)提供更加有效的方式对容器中的子元素进行排列、对齐和分配剩余空间。

@Entry
@Component
struct Login {
  @State list: listItem[] = [
    { title: '我的最爱', img: $r('app.media.ic_my_share') },
    { title: '历史记录', img: $r('app.media.ic_my_setting') },
    { title: '消息', img: $r('app.media.ic_my_scan_history') },
    { title: '购物车', img: $r('app.media.ic_my_respect') },
    { title: '我的目标', img: $r('app.media.ic_my_examine_fail') },
    { title: '圈子', img: $r('app.media.ic_my_custom_service') },
    { title: '收藏', img: $r('app.media.ic_my_examine') },
    { title: '回收站', img: $r('app.media.ic_my_feedback') }
  ];

  build() {
    // 换行控制
    Flex({wrap:FlexWrap.Wrap} ) {
      ForEach(this.list,(item:listItem) => {
        Column() {
          Image(item.img).width(24).height(24)
          Text(item.title).fontSize(12)
        }.width('25%')
        .margin({top:'8',bottom:'8'}) // 上下边距
      })
    }
    .padding(10)
    .margin(20)
    .borderRadius(10)
    .backgroundColor('#fff')

  }
}

我们首先定义了一个数组,存放列表的文字和icon,每个item,按剩余空间铺满整个屏幕。
预览效果:
flex

华为商城

最后我们来实现一个简单的华为商城效果,做android开发,我们知道最重要的组件还是列表,同样的鸿蒙提供List组件实现列表效果。
首先我们看下整体的布局:

@Entry
@Component
struct MyList {
  build() {
    Row() {
      Navigation() {
        Column() {
          TabBars()
        }
      }
      .size({ width: '100%', height: '100%' })
      .title('华为商城')
      .titleMode(NavigationTitleMode.Mini) //标题类型
    }
    .height('100%')
    .backgroundColor('#f1f3f5')
  }
}

我们首先使用一个Navigation组件实现导航切换,中间TabBars显示内容。看下TabBars自定义组件:

@Component
export struct TabBars {
  @State tabsIndex: number = 0
  @State initBarData: string[] = [
    '精选', '手机', '服饰', '穿搭', '家居'
  ]

  @Builder
  tabBarBuilder(content: string, index: number) {
    Column() {
      Text(content)
        .fontSize(this.tabsIndex == index ? 20 : 16)
        .fontColor(this.tabsIndex == index ? '#000' : '#666')
    }
  }

  build() {
    Tabs() {
      ForEach(this.initBarData, (item: string, index: number) => {
        TabContent() {
          Column() {
            if(index == 0) {
              GoodsList()
            } else {
              Text(item).fontSize(80)
            }
          }.justifyContent(FlexAlign.Center)
          .width('100%')
          .height('100%')
        }
        .tabBar(this.tabBarBuilder(item, index !== undefined ? index : 0)) // 标题
      })

    }.onChange((index: number) => {
      this.tabsIndex = index
    })
  }
}

这里用到了一个Tabs组件,主要包括TabContent和TabBar,TabContent是内容页,TabBar是导航页签栏,导航栏分为底部导航、顶部导航、侧边导航。我们这里tab第一个条目显示一个商品列表,其他tab页面显示一个文本提示。
我们看下商品列表页如何实现的:

@Component
export struct GoodsList {
  @State list: GoodSItem[] = goodsList

  build() {
    Row() {
      List({ space: 16 }) {
        ForEach(this.list, (item: GoodSItem) => {
          ListItem() {
            Row() {
              Column() {
                Image(item?.goodsImg).width('100%').height('100%')
              }
              .width('40%').height('100%')

              Column() {
                Text(item.goodsName)
                  .fontSize(16).margin({ bottom: 20 })
                Text(item.title)
                  .fontColor('#666').fontSize(12)
                  .margin({ right: 12, bottom: 10 })
                Row() {
                  Text(item.desc).fontSize(12).fontColor('#666')
                  Text(item.price).fontSize(16).fontColor('e92f4f')
                }

              }.width('60%').padding(8).height('100%')

            }.justifyContent(FlexAlign.SpaceBetween)
            .width('100%')
            .height(120)
          }

        })
      }.width('94%')
    }.width('100%')

  }
}

我们引入了一个本地数组,模拟网络请求后的数据,然后根据数据组装了一个列表页面。
本地数据结构:

export class GoodSItem {
  goodsImg: Resource;
  goodsName: string;
  title: string;
  desc: string;
  price: string

  constructor(goodsImg: Resource, goodsName:string, price:string) {
    this.goodsImg = goodsImg
    this.goodsName = goodsName
    this.title = '重磅推荐,MD新品试用中'
    this.desc = '6666人评价 95好评'
    this.price = price
  }
}

export const goodsList: GoodSItem[] = [
  new GoodSItem($r('app.media.android_fly'),'【新品上市】畅乐冰晶绿低脂新品','¥99'),
  new GoodSItem($r('app.media.android_fly'),'【新品上市】畅乐冰晶绿低脂新品11','¥199'),
  new GoodSItem($r('app.media.android_fly'),'【新品上市】畅乐冰晶绿低脂新品22','¥299'),
  new GoodSItem($r('app.media.android_fly'),'【新品上市】畅乐冰晶绿低脂新品33','¥399'),
  new GoodSItem($r('app.media.android_fly'),'【新品上市】畅乐冰晶绿低脂新品44','¥499'),
  new GoodSItem($r('app.media.android_fly'),'【新品上市】畅乐冰晶绿低脂新品','¥599'),
  new GoodSItem($r('app.media.android_fly'),'【新品上市】畅乐冰晶绿低脂新品','¥699'),
  new GoodSItem($r('app.media.android_fly'),'【新品上市】畅乐冰晶绿低脂新品','¥799'),
  new GoodSItem($r('app.media.android_fly'),'【新品上市】畅乐冰晶绿低脂新品','¥899'),
  new GoodSItem($r('app.media.android_fly'),'【新品上市】畅乐冰晶绿低脂新品','¥999'),
  new GoodSItem($r('app.media.android_fly'),'【新品上市】畅乐冰晶绿低脂新品','¥1099'),
]

最终实现效果:

shop

总结

我们通过ArkUi基础组件,实现了一些小的demo效果,通过这些demo,我们对ArkUi声明式UI框架,有个初步的认识,我们再学习一下鸿蒙的网络请求、数据存储这些,差不多算入门了。最后,我想说的是,一项新的技术,没有那么难,花点时间学习一下,还是很好入门,至于想长期从事鸿蒙开发,这点是远远不够的,当然,其实我也是面向面试学习,如果进入公司从事鸿蒙开发的,还是得继续深入学习.

项目地址

本文demo地址
完整项目地址
创作不易,辛苦给个赞,项目有帮助辛苦给个❤️,感谢。

  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值