目录

鸿蒙HarmonyOS项目实战实现微信app效果基础界面搭建

鸿蒙HarmonyOS项目实战:实现微信app效果(基础界面搭建)

最近鸿蒙HarmonyOS开发相关的消息非常的火,后续将不再支持原生Android应用,所以对于原Android应用开发对应的Harmony版本也被一系列大厂提上了日程。

本次内容是实现一个类微信app效果,计划将常规的app效果都实现一下。

功能拆分

https://i-blog.csdnimg.cn/blog_migrate/a3d1d38250f680134250d18cba1f77c3.png

上面只是一个简单的拆分示例,当我们拿到一个功能的时候,一定要先将页面进行拆分,当我们要实现的功能通过一个个子模块实现后,最终通过子模块的拼接,就可以得到一个完整的功能。

细节实现

今天第一课,先实现整体的界面搭建,最终的实现效果如下图。

https://i-blog.csdnimg.cn/blog_migrate/3645a02e32f336f8beb032a6fe41c824.png

当我们点击之后,可以切换上面的tab内容界面。

Harmony提供了很多种方式可以实现底部导航栏,真实项目使用的话,大家可以直接使用系统提供的方式即可。这里我采用的方式是自己用最基础的代码实现,这样也能联系到一些想要学习的功能,开箱即用是好的,但是也很容易让我们错过很多关键知识。

实现BottomNavigationItem

我们这里整体的底部是一个 BottomNavigation ,他是由四个 BottomNavigationItem 组合实现。首先定义一个实体类,用于存贮底部导航栏对象信息。

export class BottomNavigationEntity {
  /**
   * 底部导航tab标题
   */
  title: Resource;

  /**
   * 底部导航tab图片
   */
  image: Resource;

  /**
   * 底部导航tab图片,未选中
   */
  unCheckImage: Resource;

  /**
   * tab类型标志位
   */
  tag: number;

  constructor(tag: number, title: Resource, image: Resource, unCheckImage: Resource) {
    this.tag = tag;
    this.title = title;
    this.image = image;
    this.unCheckImage = unCheckImage;
  }
}

接下来的

https://i-blog.csdnimg.cn/blog_migrate/b475716b87cc7c328c16e5d3440d205d.png

组成是一个图标+一个文字组合而成,第一反应我们应该行到 Column 组件。

Column 组件中,用于处理组件内容对其方式使用的话flex方式。 alignItems(value: HorizontalAlign): ColumnAttribute; # 水平方向 justifyContent(value: FlexAlign): ColumnAttribute; # 垂直方向 了解了这些之后,接下来看具体 BottomNavigationItem 的封装代码。

@Preview  # 方便单个view直接预览
@Component  # 标记是一个组件,可供其他组件引用
export default struct BottomNavigationItem {
  private navigationItem: BottomNavigationEntity;
  
  # 这里的Link是用于父组件和子组件进行通信	
  @Link currentIndex: number;

  build() {
    Column({ space: 5 }) {
    # 这里判断如果当前选中的item是当前的这个,则使用选中状态图片
      Image(this.currentIndex === this.navigationItem.tag ? this.navigationItem.image : this.navigationItem.unCheckImage)
        .width(24)
        .height(24)
      Text(this.navigationItem.title)
        .fontSize(14)
        .fontColor(this.currentIndex === this.navigationItem.tag ? Color.Green : 0x333333)
    }
  }
}

代码是不是非常简单。对于 @Link 你如果现在不太清楚,也没有关系,我最终会专门进行一个讲解。

实现BottomNavigation

@Preview
@Component
export default struct BottomNavigation {
  @Link currentItemIndex: number;

  build() {
    Row({ space: 5 }) {
      //  这里通过对结合遍历,生成BottomNavigationItem进行填充BottomNavigation
      ForEach(navigationViewModel.getNavigationList(), (item: BottomNavigationEntity, index: number) => {
        # 对于这里的$currentItemIndex写法可以先将疑问留着,后续结合Link一并说明
        BottomNavigationItem({ navigationItem: item, currentIndex: $currentItemIndex })
          .onClick(() => {
          	#  点击后更新选中的item,以实现刷新界面的效果
            this.currentItemIndex = index
          })
      })
    }
    .width('100%')
    .height(65)
    .padding({
      top: 5,
      bottom: 5
    })
    .justifyContent(FlexAlign.SpaceAround)
    .backgroundColor(0xF3EEEA)
  }
}

实现WechatMainFrame

整体的界面组合使用 RelativeContainer 进行组合,将 BottomNavigation 固定于屏幕的底部,内容区域底部在 BottomNavigation 之上,顶部和屏幕顶部对其,使其填充满 BottomNavigation 之上的部分。内容区域使用 Stack 将所有的内容层叠展示,切换到哪个展示,则使用 visibility 方法设置该页面展示即可。

@Entry
@Component
struct WechatMainFrame {
  @State currentCheckIndex: number = 0;

  build() {
    RelativeContainer() {
      BottomNavigation({ currentItemIndex: $currentCheckIndex })
        .alignRules({
          bottom: { anchor: "__container__", align: VerticalAlign.Bottom },
          left: { anchor: "__container__", align: HorizontalAlign.Start }
        })
        .id("bottomNavigation")

      Stack() {
        HomeFragment().visibility(this.currentCheckIndex == 0 ? Visibility.Visible : Visibility.Hidden)
        ContactFragment().visibility(this.currentCheckIndex == 1 ? Visibility.Visible : Visibility.Hidden)
        DiscoverFragment().visibility(this.currentCheckIndex == 2 ? Visibility.Visible : Visibility.Hidden)
        MeFragment().visibility(this.currentCheckIndex == 3 ? Visibility.Visible : Visibility.Hidden)
      }
      .width('100%')
      .height('100%')
      .alignRules({
        left: { anchor: "__container__", align: HorizontalAlign.Start },
        right: { anchor: "__container__", align: HorizontalAlign.End },
        bottom: { anchor: "bottomNavigation", align: VerticalAlign.Top },
        top: { anchor: "__container__", align: VerticalAlign.Top }
      })
      .id("contentPanel")
    }
    .width('100%').height('100%')
  }
}

入口页面EntryAbility

export default class EntryAbility extends UIAbility {
  ...
  onWindowStageCreate(windowStage: window.WindowStage) {
    // Main window is created, set main page for this ability
    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');

    windowStage.loadContent('pages/WechatMainFrame', (err, data) => {
      if (err.code) {
        hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
        return;
      }
      hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
    });
  }
  ...

至此整个页面的框架结构完成了。

关于@Link相关的说明

我们对于视图更新,可以使用 @State 标记变量,但是 @State 不能进行跨文件使用。这个时候 @Link 的实现就弥补了 @State 的不足。使用 @Link 的话。子组件中被 @Link 装饰的变量与其父组件中对应的数据源建立双向数据绑定。

  • @Link装饰的变量与其父组件中的数据源共享相同的值。
  • @Link装饰器不能在@Entry装饰的自定义组件中使用。
  • @Link子组件从父组件初始化@State的语法为Comp({ aLink: this.aState })。同样Comp({aLink: $aState})也支持。

https://i-blog.csdnimg.cn/blog_migrate/b556da6e1f1bb783736ca950b00d94af.png

下面我们回到上面的代码中。结合代码进行分析。 当我们在 BottomNavigation.onClick(() => { this.currentItemIndex = index }) 在点击之后,会更改 @Link currentItemIndex: number; 触发界面ui的更改。而 BottomNavigationItem({ navigationItem: item, currentIndex: $currentItemIndex }) 中,我们需要把选中的item的 index 值传递给 BottomNavigationItem 本身。而作为传递的值,则需要使用 \$ 标记。这样点击之后会将 BottomNavigationItem 的值也触发更改,以达到更改布局效果。 BottomNavigationItem\ 的判断也会根据这个值变化而变化。

点击之后,除了对 BottomNavigation 的状态更新之外,还需要对内容区域进行判断展示不同的界面。因此 BottomNavigation@Link currentItemIndex: number; 又要和 WechatMainFrame@State currentCheckIndex: number = 0; 进行双向绑定 BottomNavigation({ currentItemIndex: $currentCheckIndex }) 。最终当我们点击 BottomNavigationonclick 的时候,就会向上和 WechatMainFrame 双向绑定更改内容区域,也会和 BottomNavigationItem 双向绑定更改底部导航展示。


最后,有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的 鸿蒙(Harmony NEXT)资料 用来跟着学习是非常有必要的。

为了能够帮助大家快速掌握 鸿蒙(Harmony NEXT) 应用开发技术知识。 在此给大家分享一下我结合鸿蒙最新资料整理出来的鸿蒙南北向开发学习路线以及整理的最新版鸿蒙学习文档资料。

这份鸿蒙(Harmony NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony 多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等 )鸿蒙(Harmony NEXT) 技术知识点。

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

如果你是一名有经验的资深Android移动开发、Java开发、前端开发、对鸿蒙感兴趣以及转行人员,可以直接领取这份资料

获取这份完整版高清学习路线,请点击→

鸿蒙(Harmony NEXT)最新学习路线

https://i-blog.csdnimg.cn/blog_migrate/8fb90f03f52981850522a8d70bfe821d.png

  • HarmonOS基础技能

https://i-blog.csdnimg.cn/blog_migrate/d15791a8d9157b12cf470e6e20e199cd.png

  • HarmonOS就业必备技能 https://i-blog.csdnimg.cn/blog_migrate/219a3f80b24947602f5ce80869c0f0d1.png
  • HarmonOS多媒体技术

https://i-blog.csdnimg.cn/blog_migrate/f76470c4171a878d5f6071f6d009b828.png

  • 鸿蒙NaPi组件进阶

https://i-blog.csdnimg.cn/blog_migrate/8755cfeac3a887ec19fb168f7164234c.png

  • HarmonOS高级技能

https://i-blog.csdnimg.cn/blog_migrate/1e210328c1ebf43f08d3b6c5f5c13b48.png

  • 初识HarmonOS内核 https://i-blog.csdnimg.cn/blog_migrate/24384aae472f78c055f7bf545467db7f.png
  • 实战就业级设备开发

https://i-blog.csdnimg.cn/blog_migrate/9b0c4eb9a30ca059d28eceb4727b593e.png

有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的 鸿蒙(OpenHarmony )学习手册(共计1236页)鸿蒙(OpenHarmony )开发入门教学视频 ,内容包含: ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→

《鸿蒙 (OpenHarmony)开发入门教学视频》

https://i-blog.csdnimg.cn/blog_migrate/9b893c2a4956d6ce72b63212f9216eab.png

《鸿蒙生态应用开发V2.0白皮书》

https://i-blog.csdnimg.cn/blog_migrate/343917b8910aff13b48316fe3db39da6.jpeg

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

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

https://i-blog.csdnimg.cn/blog_migrate/2e05bbd2cb0f05ec297905ba57f803c2.png

《鸿蒙开发基础》

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

https://i-blog.csdnimg.cn/blog_migrate/48e16dbee395ba8de1264149330856d4.png

《鸿蒙开发进阶》

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

https://i-blog.csdnimg.cn/blog_migrate/adf72eca696abc1415cd768fceda1af7.png

《鸿蒙进阶实战》

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

https://i-blog.csdnimg.cn/blog_migrate/c077a46bb540fc657713d99f39e9c74c.png

获取以上完整鸿蒙HarmonyOS学习资料,请点击→

总结

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

https://i-blog.csdnimg.cn/blog_migrate/926f3f942f098baebec15ecf79df9ca9.png