自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

想了解更多關(guān)于開源的內(nèi)容,請訪問:

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

https://ost.51cto.com

前言

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

效果展示

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

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

關(guān)于eTS

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

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

TypeScript 和 JavaScript 的區(qū)別:

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

布局容器組件

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

繪制組件

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

自定義組件

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

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

自定義組件常用屬性

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

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

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

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

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

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

const nextMonthDays = [];
//獲取下個月最大天數(shù)
let curLastDay = new Date(year, month, 0).getDate();
//獲取當(dāng)前月份1號在一周的第幾天
let startWeek = new Date(year, month, 1).getDay();
//一頁的天數(shù)減去當(dāng)前月份的天數(shù)和上個月的天數(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ù),例如:屏幕分辨率、橫豎屏切換來修改應(yīng)用的樣式。

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

import mediaquery from '@ohos.mediaquery'

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

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

定義觸發(fā)回調(diào)函數(shù),當(dāng)匹配到媒體查詢條件時會觸發(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
  }
}

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

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

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

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

定義一個類并實(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() {
  }
}

在頁面中導(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)在一頁42個格子上顯示上個月、當(dāng)前月、下個月的日期,通過日歷應(yīng)用的開發(fā)了解到了ArkUI組件的一些用法,生命周期和數(shù)據(jù)的加載過程,對之后的應(yīng)用開發(fā)有很大的幫助。

想了解更多關(guān)于開源的內(nèi)容,請訪問:

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

https://ost.51cto.com

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

2022-07-26 14:40:42

ArkUIJS

2022-05-27 14:55:34

canvas畫布鴻蒙

2022-08-04 13:55:08

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

2022-09-15 15:04:16

ArkUI鴻蒙

2022-09-20 14:35:59

ArkUI鴻蒙JS

2023-08-17 15:04:22

2022-08-05 19:37:59

鴻蒙Api框架

2022-11-02 16:06:54

ArkUIETS

2022-10-24 14:49:54

ArkUI心電圖組件

2021-12-27 15:10:55

鴻蒙HarmonyOS應(yīng)用

2022-06-28 14:42:26

ETS購物車應(yīng)用

2022-03-17 15:28:18

五子棋HarmonyOSJSAPI

2022-09-16 15:34:32

CanvasArkUI

2022-10-17 14:36:09

ArkUI虛擬搖桿組件

2022-09-14 15:17:26

ArkUI鴻蒙

2022-08-05 19:27:22

通用API鴻蒙

2022-01-07 09:56:16

鴻蒙HarmonyOS應(yīng)用

2021-12-01 15:40:23

鴻蒙HarmonyOS應(yīng)用

2009-06-19 09:52:46

Acegi安全框架Spring框架

2022-09-21 14:51:21

ArkUI信件彈出
點(diǎn)贊
收藏

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