偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

OpenHarmony - 基于ArkUI框架實(shí)現(xiàn)日歷應(yīng)用

系統(tǒng) OpenHarmony
eTS語(yǔ)言:基于TypeScript(簡(jiǎn)稱(chēng)TS)拓展的出來(lái)的,是OpenHarmony應(yīng)用開(kāi)發(fā)語(yǔ)言,使用ArkUI框架提供的組件進(jìn)行界面開(kāi)發(fā)。

想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO 鴻蒙開(kāi)發(fā)者社區(qū)

https://ost.51cto.com

前言

對(duì)于剛剛接觸OpenHarmony應(yīng)用開(kāi)發(fā)的開(kāi)發(fā)者,最快的入門(mén)方式就是開(kāi)發(fā)一個(gè)簡(jiǎn)單的應(yīng)用,下面記錄了一個(gè)日歷應(yīng)用的開(kāi)發(fā)過(guò)程,通過(guò)日歷應(yīng)用的開(kāi)發(fā),來(lái)熟悉基本圖形的繪制,ArkUI的組件的使用,UI組件生命周期,加深對(duì)OpenHarmony應(yīng)用開(kāi)發(fā)的理解。

效果展示

開(kāi)發(fā)環(huán)境

  • 開(kāi)發(fā)工具:DevEco Studio 3.1 Release
  • 開(kāi)發(fā)環(huán)境:OpenHarmony API 9
  • 開(kāi)發(fā)語(yǔ)言:eTS

關(guān)于eTS

eTS語(yǔ)言:基于TypeScript(簡(jiǎn)稱(chēng)TS)拓展的出來(lái)的,是OpenHarmony應(yīng)用開(kāi)發(fā)語(yǔ)言,使用ArkUI框架提供的組件進(jìn)行界面開(kāi)發(fā)。

什么是TypeScript:
TypeScript 是微軟開(kāi)發(fā)的一個(gè)開(kāi)源的編程語(yǔ)言,是面向?qū)ο髲?qiáng)類(lèi)型化的,在 JavaScript 的基礎(chǔ)上引入了靜態(tài)類(lèi)型、類(lèi)、接口的概念。

TypeScript 和 JavaScript 的區(qū)別:

  • TypeScript 是 JavaScript 的超集,在JavaScript的基礎(chǔ)上拓展了語(yǔ)法,包含了 JavaScript 的所有元素
  • 在TypeScript 中的數(shù)據(jù)要求有明確的類(lèi)型,而JavaScript中沒(méi)有
  • TypeScript在編譯時(shí)可以發(fā)現(xiàn)錯(cuò)誤,JavaScript只有在運(yùn)行時(shí)報(bào)錯(cuò)

布局容器組件

  • Column :沿垂直方向布局的容器,可以包含多個(gè)子組件
  • Row:沿水平方向布局容器,可以包含多個(gè)子組件
  • Stack:堆疊容器,子組件按照順序依次入棧,后一個(gè)子組件覆蓋前一個(gè)子組件,可以包含多個(gè)子組件
  • Flex:彈性布局,元素在容器內(nèi)水平居中,垂直等間隔分散,可以包含多個(gè)子組件
  • Scroll:可滑動(dòng)的容器組件,當(dāng)子組件的布局尺寸超過(guò)父組件的視口時(shí),內(nèi)容可以滑動(dòng),內(nèi)部只支持單個(gè)子組件,可支持垂直或者水平滑動(dòng)
  • Tabs:一種可以通過(guò)頁(yè)簽進(jìn)行內(nèi)容視圖切換的容器組件,每個(gè)頁(yè)簽對(duì)應(yīng)一個(gè)內(nèi)容視圖,只能包含子組件TabContent
  • List:列表包含一系列相同寬度的列表項(xiàng)。適合連續(xù)、多行呈現(xiàn)同類(lèi)數(shù)據(jù),例如圖片和文本,只能包含ListItem子組件
  • Swiper:滑動(dòng)容器,提供左右切換子組件顯示的能力,可以包含多個(gè)子組件
  • Grid:網(wǎng)格容器,由“行”和“列”分割的單元格所組成,通過(guò)指定“項(xiàng)目”所在的單元格做出各種各樣的布局,只能包含GridItem子組件

繪制組件

  • Circle:圓形繪制組件
  • Ellipse:橢圓繪制組件
  • Line:直線繪制組件
  • Polyline:折線繪制組件
  • Polygon:多邊形繪制組件
  • Path:路徑繪制組件
  • Rect:矩形繪制組件
  • Shape:繪制組件的父組件,父組件中會(huì)描述所有繪制組件均支持的通用屬性。

自定義組件

自定義組件生命周期函數(shù)

  • aboutToAppear:在組件的 build 函數(shù)之前執(zhí)行,可以做數(shù)據(jù)的初始化操作。
  • aboutToDisappear:在組件銷(xiāo)毀之前執(zhí)行,不允許改變狀態(tài)變量,會(huì)導(dǎo)致應(yīng)用程序行為不穩(wěn)定,可以做資源的釋放操作。
  • onPageShow:僅@Entry修飾的自定義組件生效,應(yīng)用進(jìn)入前臺(tái)臺(tái),頁(yè)面顯示時(shí)觸發(fā)。
  • onPageHide:僅@Entry修飾的自定義組件生效,應(yīng)用進(jìn)入后臺(tái),頁(yè)面消失時(shí)觸發(fā)。

自定義組件常用屬性

  • @State :變量需要本地初始化,初始化的值可以被構(gòu)造參數(shù)覆蓋;
  • @Prop:必須通過(guò)構(gòu)造函數(shù)參數(shù)初始化,屬于單向數(shù)據(jù)綁定,使用其父組件提供的@State變量進(jìn)行初始化
  • @Link:必須通過(guò)構(gòu)造函數(shù)參數(shù)進(jìn)行初始化,屬于雙向數(shù)據(jù)綁定,子組件對(duì)@Link變量的更改將同步修改父組件的@State變量;

實(shí)現(xiàn)過(guò)程

日歷一頁(yè)顯示42天,包括上個(gè)月、當(dāng)前月、下個(gè)月的天數(shù),上個(gè)月和下個(gè)月的日期顯示灰色,點(diǎn)擊日期顯示選中效果。
支持選擇年份、月份,指定一個(gè)日期,獲取當(dāng)前月的天數(shù),根據(jù)該月1號(hào)在一周中的第幾天,獲取上個(gè)月顯示的天數(shù),以及下個(gè)月顯示的天數(shù)。

獲取上一個(gè)月的天數(shù),根據(jù)指定月份的1號(hào)在一周的第幾天,上月最大天數(shù),計(jì)算出上個(gè)月天數(shù),以object的形式添加到數(shù)組,以便區(qū)分,代碼如下:

const prevMonthDays = [];
//獲取上個(gè)月最大天數(shù)
let prevLastDay = new Date(year, month-1, 0).getDate();
//獲取某月1號(hào)所在一周的第幾天
let startWeek = new Date(year, month, 1).getDay();
// 上個(gè)月的最大天數(shù)減去當(dāng)前月1號(hào)所在一周的第幾天
for (let i = prevLastDay - startWeek + 1; i <= prevLastDay; i++) {
      prevMonthDays.push({
        date: new Date(year, month - 1, i),
        status: 'prev'
      });
}

獲取下一個(gè)月的天數(shù),根據(jù)當(dāng)前月份的1號(hào)在一周的第幾天,當(dāng)前月份的最大天數(shù),計(jì)算出下個(gè)月天數(shù),以object的形式添加到數(shù)組,以便區(qū)分,代碼如下:

const nextMonthDays = [];
//獲取下個(gè)月最大天數(shù)
let curLastDay = new Date(year, month, 0).getDate();
//獲取當(dāng)前月份1號(hào)在一周的第幾天
let startWeek = new Date(year, month, 1).getDay();
//一頁(yè)的天數(shù)減去當(dāng)前月份的天數(shù)和上個(gè)月的天數(shù)
for (let i = 1; i <= 42 - startWeek - curLastDay + 1; i++) {
      nextMonthDays.push({
        date: new Date(year, month + 1, i),
        status: 'next'
      });
}

獲取當(dāng)前月的天數(shù),以object的形式添加到數(shù)組,以便區(qū)分,代碼如下:

let curLastDay = new Date(year, month, 0).getDate();
for (let i = 1; i <= curLastDay; i++) {
      curMonthDays.push({
        date: new Date(year, month, i),
		
        status: 'current'
      });
}

屏幕適配

屏幕適配需要用到媒體查詢的接口,可以根據(jù)設(shè)備參數(shù),例如:屏幕分辨率、橫豎屏切換來(lái)修改應(yīng)用的樣式。

首先導(dǎo)入媒體查詢模塊:

import mediaquery from '@ohos.mediaquery'

然后通過(guò)matchMediaSync接口設(shè)置媒體查詢條件,并保存返回的條件監(jiān)聽(tīng)句柄,例如:監(jiān)聽(tīng)設(shè)備類(lèi)型,橫豎屏狀態(tài)。

//監(jiān)聽(tīng)橫豎屏狀態(tài)
private listener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('(orientation: landscape)');
//監(jiān)聽(tīng)當(dāng)前設(shè)備類(lèi)型
private deviceListener: mediaquery.MediaQueryListener = mediaquery.matchMediaSync('screen and (device-type: default)');

定義觸發(fā)回調(diào)函數(shù),當(dāng)匹配到媒體查詢條件時(shí)會(huì)觸發(fā)此回調(diào)函數(shù)。

onOrientationChange = (mediaQueryResult) => {
  if (mediaQueryResult.matches) {
    this.calendarWidth = "70%"
    this.titleBarLeft = 80
  } else {
    this.calendarWidth = "100%"
    this.titleBarLeft = 20
  }
}
onDeviceTypeChange = (mediaQueryResult) => {
  if(mediaQueryResult.matches){
    this.titleBarLeftTop = 10
    this.weekHeight = 30
    this.pikerDialogHeight = 200
    console.log("onDeviceTypeChange  device-type: default")
  }else{
    this.titleBarLeftTop = 40
    this.weekHeight = 50
    this.pikerDialogHeight = 280
  }
}

通過(guò)條件監(jiān)聽(tīng)句柄去注冊(cè)回調(diào)函數(shù),在 aboutToAppear 組件初始化的時(shí)候執(zhí)行注冊(cè),退出時(shí)銷(xiāo)毀監(jiān)聽(tīng)。

//組件初始化
aboutToAppear() {
  this.listener.on('change', this.onOrientationChange);
}
//組件銷(xiāo)毀
aboutToDisappear(){
  this.listener.off('change', this.onOrientationChange);
}

數(shù)據(jù)懶加載

當(dāng)列表加載的數(shù)據(jù)過(guò)大時(shí),直接采用循環(huán)渲染方式,導(dǎo)致頁(yè)面啟動(dòng)時(shí)間過(guò)長(zhǎng),可以使用LazyForEach組件進(jìn)行數(shù)據(jù)的懶加載進(jìn)行優(yōu)化,按需加載數(shù)據(jù)并創(chuàng)建相應(yīng)組件。

定義一個(gè)類(lèi)并實(shí)現(xiàn)IDataSource接口:

export class YearData implements IDataSource{

  private list: number[] = []
  private listener: DataChangeListener

  constructor(list: number[]) {
    this.list = list
  }

  totalCount(): number {
    return this.list.length
  }

  getData(index: number): any {
    return this.list[index]
  }

  getDataIndex(data:any){
    return this.list.indexOf(data)
  }

  registerDataChangeListener(listener: DataChangeListener): void {
    this.listener = listener
  }

  unregisterDataChangeListener() {
  }
}

在頁(yè)面中導(dǎo)入并使用。

import { YearData } from '../datasource/YearData'

private data: YearData = new YearData([])
LazyForEach(this.data, (item: string) => {
        ListItem() {
          Row() {
            Text(item).fontSize(20).margin({ left: 10 })
          }
        }
        .onClick(() => {
          this.data.pushData('item value: ' + this.data.totalCount())
        })
      }, item => item)
}

總結(jié)

日歷應(yīng)用實(shí)現(xiàn)在一頁(yè)42個(gè)格子上顯示上個(gè)月、當(dāng)前月、下個(gè)月的日期,通過(guò)日歷應(yīng)用的開(kāi)發(fā)了解到了ArkUI組件的一些用法,生命周期和數(shù)據(jù)的加載過(guò)程,對(duì)之后的應(yīng)用開(kāi)發(fā)有很大的幫助。

想了解更多關(guān)于開(kāi)源的內(nèi)容,請(qǐng)?jiān)L問(wèn):

51CTO 鴻蒙開(kāi)發(fā)者社區(qū)

https://ost.51cto.com

責(zé)任編輯:jianghua 來(lái)源: 51CTO 鴻蒙開(kāi)發(fā)者社區(qū)
相關(guān)推薦

2022-07-26 14:40:42

ArkUIJS

2022-05-27 14:55:34

canvas畫(huà)布鴻蒙

2022-09-15 15:04:16

ArkUI鴻蒙

2022-09-20 14:35:59

ArkUI鴻蒙JS

2022-08-04 13:55:08

拼數(shù)字小游戲鴻蒙

2023-08-17 15:04:22

2022-08-05 19:37:59

鴻蒙Api框架

2022-10-24 14:49:54

ArkUI心電圖組件

2022-11-02 16:06:54

ArkUIETS

2021-12-27 15:10:55

鴻蒙HarmonyOS應(yīng)用

2023-08-17 15:01:08

ArkUI布局渲染

2022-07-20 15:32:25

時(shí)鐘翻頁(yè)Text組件

2022-09-16 15:34:32

CanvasArkUI

2022-06-28 14:42:26

ETS購(gòu)物車(chē)應(yīng)用

2022-03-17 15:28:18

五子棋HarmonyOSJSAPI

2022-09-14 15:17:26

ArkUI鴻蒙

2022-08-05 19:27:22

通用API鴻蒙

2022-10-17 14:36:09

ArkUI虛擬搖桿組件

2023-02-13 15:54:49

2022-01-07 09:56:16

鴻蒙HarmonyOS應(yīng)用
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)