零基础小白从零到一肝鸿蒙项目

64 阅读5分钟

一.相关资源的准备及配置

1.颜色以及名称

a.颜色资源 resources/base/element/color.json

{
  "color": [
    {
      "name": "common_gray_01",
      "value": "#979797"
    },
    {
      "name": "common_gray_02",
      "value": "#848484"
    },
    {
      "name": "common_gray_03",
      "value": "#666666"
    },
    {
      "name": "common_gray_bg",
      "value": "#f3f4f5"
    },
    {
      "name": "common_gray_border",
      "value": "#e8e7ee"
    },
    {
      "name": "common_main_color",
      "value": "#FA6D1D"
    },
    {
      "name": "common_green",
      "value": "#41B883"
    },
    {
      "name": "common_blue",
      "value": "#3266EE"
    },
    {
      "name": "common_blue_bg",
      "value": "#EDF2FF"
    },
    {
      "name": "black",
      "value": "#131313"
    },
    {
      "name": "white",
      "value": "#ffffff"
    },
    {
      "name": "home_gray",
      "value": "#EDECF2"
    }
  ]
}

2.桌面头像以及名称修改

a.module.json5//图标修改

"abilities": [

​ {

​ "name": "EntryAbility",

​ "srcEntry": "./ets/entryability/EntryAbility.ets",

​ "description": "$string:EntryAbility_desc",

  • ​ "icon": "media:startIcon","label":"media:startIcon", "label": "string:EntryAbility_label",

​ "startWindowIcon": "media:startIcon","startWindowBackground":"media:startIcon", "startWindowBackground": "color:start_window_background",

​ "exported": true,

​ "skills": [

​ {

​ "entities": [

​ "entity.system.home"

​ ],

​ "actions": [

​ "action.system.home"

​ ]

​ }

​ ]

​ }

],

b."label": "$string:EntryAbility_label"--resources/zh_CN/element/string.json(Ctrl+单点图标修改)

{

"name": "EntryAbility_label",

"value": "面试通"

}

3.APP设置修改图像和图标

a.设置应用与元服务的图标和名称

AppScope/resources/base/element/string.json修改名称

{

"string": [

​ {

​ "name": "app_name",

​ "value": "面试通"

​ }

]

}

b.修改图标记(名称要和默认图标的)

AppScope/resources/base/media/app_icon.png 替换 logo

二.git 仓库在编译器中进行对远程仓库的推送

  1. 在gitee上新建一个远程仓库

  2. 在桌面上新建一个空的文件夹然后对数据进行克隆

  3. 把克隆后的.git 到你的项目中 -> 不用git init、git remote add.

  4. 登陆后就立刻进行推送

三.通用工具的封装

  1. 日志工具的封装

A. hilog和console区别?

console 基于 hilog 封装,默认的 domain/tag 是 A03D00/JSAPP.

B.封装后:\entry\src\main\ets\commons\utils\Logger.ets

// 封装代码做法不唯一  个人主观 !!

import { hilog } from '@kit.PerformanceAnalysisKit';

// 常量
const LOGGER_PREFIX: string = 'interview_success_logger';

// hilog.debug(0x0000, "首页", `%{public}s -  %{public}s`, "轮播图", "播放")
class Logger {
  // 域 0x0000
  private domain: number;
  // "首页" 前缀
  private prefix: string;
  // `%{public}s -  %{public}s`
  private format: string = '%{public}s, %{public}s';

  constructor(prefix: string = '', domain: number = 0x0000) {
    this.prefix = prefix;
    this.domain = domain;
  }

  debug(...args: string[]): void {
    hilog.debug(this.domain, this.prefix, this.format, args);
  }

  info(...args: string[]): void {
    hilog.info(this.domain, this.prefix, this.format, args);
  }

  warn(...args: string[]): void {
    hilog.warn(this.domain, this.prefix, this.format, args);
  }

  error(...args: string[]): void {
    hilog.error(this.domain, this.prefix, this.format, args);
  }
}

export const logger = new Logger(LOGGER_PREFIX, 0x1234);

C. 封装后

   hilog.debug(0x0000, "首页", `%{public}s -  %{public}s`, "轮播图", "播放")
         // 普通的输出
        hilog.info(0x0000, "首页", `%{public}s -  %{public}s`, "轮播图", "播放")
          // 警告
         hilog.warn(0x0000, "首页", `%{public}s -  %{public}s`, "轮播图", "播放")
          // 一般错误
         hilog.error(0x0000, "首页", `%{public}s -  %{public}s`, "轮播图", "播放")
         // 重大错题
          hilog.fatal(0x0000, "首页", `%{public}s -  %{public}s`, "轮播图", "播放")

同级目录下新建Index, 负责统一导入和导出 entry/src/main/ets/commons/utils/index.ets

// 功能 负责统一导出utils下所有的封装好的功能
// 个人主观的!!

// from 导入 Logger 一些东西
// * 导入 Logger - 里面所有的内容
// export 把刚才导入的Logger里面的东西,全部导出
export * from "./Logger"
  1. 设置沉浸式以及封装(设置全屏状态)

A.在D:\mianshitong1\entry\src\main\ets**entryability**\EntryAbility.ets中进行未封装的沉浸式设置

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

  // 1 获取最新的窗口对象
  let windowClass = await window.getLastWindow(this.context);
  // 2 设置沉浸式 全屏
  windowClass.setWindowLayoutFullScreen(true)
  windowStage.loadContent('pages/Index', (err) => {
    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.');
  });
}

B.进行封装entry\src\main\ets\commons\utils\FullScreen.ets

import { window } from '@kit.ArkUI';

class FullScreen {
  /**
   * 启动沉浸式
   */
  async enable() {
    // 读取存储起来 数据 上下文
    const ctx = AppStorage.get<Context>("EntryAbilityContext")

    // 1 获取最新的窗口对象
    let windowClass = await window.getLastWindow(ctx!);
    // 2 设置沉浸式 全屏
    windowClass.setWindowLayoutFullScreen(true)
  }

  // 禁用沉浸式
  async disable() {
    const ctx = AppStorage.get<Context>("EntryAbilityContext")
    // 1 获取最新的窗口对象
    let windowClass = await window.getLastWindow(ctx!);
    // 2 设置沉浸式 全屏
    windowClass.setWindowLayoutFullScreen(false)
  }
}

export const fullScreen = new FullScreen()

entryability进行****简洁调用

onWindowStageCreate(windowStage: window.WindowStage) {
  // Main window is created, set main page for this ability
  hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
  // 存储起来 在另外页面使用
  AppStorage.setOrCreate("EntryAbilityContext",this.context)
  fullScreen.enable()

  windowStage.loadContent('pages/Index', (err) => {
    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.');
  });
}

C.在设置chernjins设置后,考虑安全区域

设置避让高度以及底部高度处理

import { window } from '@kit.ArkUI';
import { logger } from '.';

class FullScreen {
  /**
   * 启动沉浸式
   */
  async enable() {
    // 读取存储起来 数据 上下文
    const ctx = AppStorage.get<Context>("EntryAbilityContext")

    // 1 获取最新的窗口对象
    let windowClass = await window.getLastWindow(ctx!);
    // 2 设置沉浸式 全屏
    windowClass.setWindowLayoutFullScreen(true)

    //   输出 安全区域  顶部导航栏高度
    const area = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM)
    // area.topRect.top px单位
    // 转换成 vp单位 px2vp()
    const top = px2vp(area.topRect.height)
    //   存一下系统状态栏的高度
    AppStorage.setOrCreate("areaTop", top)


    // 底部导航条 区域
    const bottomArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR)
    const bottom = px2vp(bottomArea.bottomRect.height)
    AppStorage.setOrCreate("areaBottom", bottom)


  }

  // 禁用沉浸式
  async disable() {
    const ctx = AppStorage.get<Context>("EntryAbilityContext")
    // 1 获取最新的窗口对象
    let windowClass = await window.getLastWindow(ctx!);
    // 2 设置沉浸式 全屏
    windowClass.setWindowLayoutFullScreen(false)
  }
}

export const fullScreen = new FullScreen()
  1. 状态栏的封装处理

A.未封装的处理

.onClick(async () => {
        try { //   全局应用中上下文对象
            // 读取存储起来 数据 上下文
            const ctx = AppStorage.get<Context>("EntryAbilityContext") as Context
           //   获取window对象
           const win = await window.getLastWindow(ctx)
         //   设置状态栏颜色
          win.setWindowSystemBarProperties({
            // 状态栏中系统文字的颜色 颜色 补全,不要省略
           // statusBarContentColor: "#D1DEE8"
              statusBarContentColor: "#FF6A15"
           })
          } catch (e) {
           console.log("e", e.message)
          }

        })

B.封装处理 StatusBar

\entry\src\main\ets\commons\utils\StatusBar.ets

import { window } from '@kit.ArkUI'
import { logger } from './Logger'

class StatusBar {
  /**
   * 设置状态栏内容白色
   */
  async setDarkBar() {
  // 这里用到的颜色 写完整 不要 #f00 失效!!! 
    await this.setBar({ statusBarContentColor: '#000000' })
  }

  /**
   * 设置状态栏内容黑色
   */
  async setLightBar() {
    await this.setBar({ statusBarContentColor: '#FFFFFF' })
  }

  /**
   * 设置对象 设置状态栏颜色
   * @param  {window.SystemBarProperties}  config 配置信息
   */
  async setBar(config: window.SystemBarProperties) {
    try {
      const context = AppStorage.get<Context>('EntryAbilityContext')
      if (context) {
        const win = await window.getLastWindow(context)
        await win.setWindowSystemBarProperties(config)
      }
    } catch (e) {
      logger.error('StatusBar setBar', JSON.stringify(e))
    }
  }
}

export const statusBar = new StatusBar()

四.提取常用的字符串到 常量文件中

  1. 新建常量文件

\entry\src\main\ets\commons\``constants\index``.ets项目中用到的常量 一般都是纯大写_间隔

// 项目中用到的常量 一般都是纯大写_间隔

/**
 * EntryAbilityContext 字段名
 */
export const ENTRY_ABILITY_CONTEXT = "EntryAbilityContext"

/**
 * 安全区域 顶部 状态栏高度 vp单位
 */
export const AREA_TOP = "areaTop"

/**
 * 安全区域 底部 导航栏高度 vp单位
 */
export const AREA_BOTTOM = "areaBottom"

五.项目页面搭建---Tabs搭建导航栏

  1. 高亮以及滑动事件

img

img

  1. 四个页面的逻辑判断

Tabs() {
  ForEach(this.tabList, (item: TabItem, index: number) => {
    TabContent() {
      if (index === 0) {
        HomePage()
      } else if (index === 1) {
        ProjectPage()
      } else if (index === 2) {
        InterviewPage()
      } else if (index === 3) {
        MinePage()
      }
    }
    .tabBar(this.aBUilder(item, index))
  })

}
// .scrollable(false)
.onAnimationStart((index, targetIndex) => {
  this.activeIndex = targetIndex
})
.onTabBarClick((index: number) => {
  this.activeIndex = index
}).divider({ strokeWidth: 0.5, color: $r('app.color.common_gray_border') })
.barPosition(BarPosition.End)
  1. HomePage()

A.顶部安全区

import { HcSearchBox } from '../commons/components/HcSearchBox'
import { AREA_TOP } from '../commons/constants'

@Component
export struct HomePage {
  @StorageProp(AREA_TOP)
  areaTop: number = 0

  build() {
    Column() {
      // 1. 顶部工具栏
      Row({ space: 16 }) {
        // 1.1 扫码小组件
        Image($r('app.media.ic_home_scan'))
          .width(24)
          .aspectRatio(1)
        Blank()
        // 1.2 搜索框组件
        // TODO 搜索组件
        HcSearchBox({ layoutWeightValue: 1 })

        //   1.3 打卡
        Row() {
          if (false) {
            //   为没有打开 显示打卡
            Text("打卡")
              .fontSize(30)
          } else {
            Column() {
              Text("已经续打卡")
                .fontSize(14)
              Text() {
                Span("1")
                  .fontSize(30)
                Span("天")
              }
            }
          }
        }
        .backgroundImage($r("app.media.ic_common_clocked"))
        .width(80)
        .height(40)
      }
      .padding({ left: 16, right: 16 })
      .height(64)
      .width('100%')
    }
    .width('100%')
    .height('100%')
    .backgroundColor($r('app.color.common_gray_bg'))
    .padding({
      top: this.areaTop
    })
  }
}