鴻蒙NEXT開發案例:光強儀

zhongcx發表於2024-11-13

【引言】

本文將介紹如何使用鴻蒙NEXT框架開發一個簡單的光強儀應用,該應用能夠實時監測環境光強度,並給出相應的場景描述和活動建議。

【環境準備】

電腦系統:windows 10

開發工具:DevEco Studio NEXT Beta1 Build Version: 5.0.3.806

工程版本:API 12

真機:mate60 pro

語言:ArkTS、ArkUI

【功能實現】

1. 專案結構

本專案主要由以下幾個部分組成:

  • LightIntensityItem 類:用於定義光強度範圍及其相關資訊,包括光強度的起始值、終止值、型別、描述和建議活動。透過建構函式初始化這些屬性,便於後續使用。
  • LightIntensityMeter 元件:這是光強儀的核心,包含狀態管理、感測器初始化和光強度更新等功能。元件使用 @State 裝飾器來管理當前光強度值和型別,並在元件即將出現時獲取感測器列表。
  • 感測器資料處理:透過監聽環境光感測器的資料,實時更新當前光強度值,並根據光強度範圍更新當前型別。這一過程確保了使用者能夠獲得最新的環境光資訊。

2. 介面佈局

光強儀的使用者介面使用了鴻蒙系統的佈局元件,包括 ColumnRow。介面展示了當前光強度值和型別,並透過儀表元件直觀地顯示光強度。使用者可以清晰地看到光強度的變化,並獲得相應的場景描述和活動建議。

  • 儀表元件:用於顯示當前光強度值,採用了動態更新的方式,確保使用者能夠實時看到光強度的變化。
  • 資訊展示:透過遍歷光強度範圍列表,展示每個型別的光強度範圍、描述和建議活動。這一部分為使用者提供了實用的資訊,幫助他們根據環境光條件做出相應的決策。

3. 總結

透過本案例,開發者可以學習到如何在鴻蒙系統中使用感測器服務和元件化開發方式,構建一個功能完整的光強儀應用。該應用不僅能夠實時監測光強度,還能根據不同的光強度範圍提供實用的建議,提升使用者體驗。

【完整程式碼】

import { sensor } from '@kit.SensorServiceKit'; // 匯入感測器服務套件
import { BusinessError } from '@kit.BasicServicesKit'; // 匯入業務錯誤類

// 定義一個光強度項類,用於儲存不同光強度範圍的資訊
class LightIntensityItem {
  luxStart: number; // 光感強度範圍起點
  luxEnd: number; // 光感強度範圍終點
  type: string; // 型別
  description: string; // 場景描述
  recommendation: string; // 建議活動

  // 建構函式,初始化物件屬性
  constructor(luxStart: number, luxEnd: number, type: string, description: string, recommendation: string) {
    this.luxStart = luxStart;
    this.luxEnd = luxEnd;
    this.type = type;
    this.description = description;
    this.recommendation = recommendation;
  }
}

// 使用裝飾器定義元件,該元件是光強度計
@Entry
@Component
struct LightIntensityMeter {
  @State currentType: string = ""; // 當前光強度型別
  @State currentIntensity: number = 0; // 當前光強度值
  @State lightIntensityList: LightIntensityItem[] = [// 不同光強度範圍的列表
    new LightIntensityItem(0, 1, '極暗', '夜晚戶外,幾乎沒有光源。', '不宜進行任何活動,適合完全休息。'),
    new LightIntensityItem(1, 10, '很暗', '夜晚室內,只有微弱的燈光或月光。', '只適合睡覺,避免使用電子裝置。'),
    new LightIntensityItem(10, 50, '暗', '清晨或傍晚,自然光較弱。', '輕鬆休閒,避免長時間閱讀,適合放鬆。'),
    new LightIntensityItem(50, 100, '較暗', '白天陰天,室內光線柔和。', '日常生活,短時間閱讀,適合輕度活動。'),
    new LightIntensityItem(100, 300, '適中', '白天多雲,室內光線適中。', '工作學習,適度閱讀,適合大部分室內活動。'),
    new LightIntensityItem(300, 500, '較亮', '白天晴朗,室內光線充足。', '正常工作學習,長時間閱讀,適合大部分活動。'),
    new LightIntensityItem(500, 1000, '亮', '陰天室外,自然光較強。', '戶外活動,注意防曬,適合戶外休閒。'),
    new LightIntensityItem(1000, 100000, '爆表了', '夏季正午直射陽光,自然光極其強烈。',
      '儘可能避免直視太陽,戶外活動需戴太陽鏡,注意防曬。'),
  ];

  // 當元件即將出現時呼叫的方法
  aboutToAppear(): void {
    sensor.getSensorList((error: BusinessError) => { // 獲取感測器列表
      if (error) { // 如果有錯誤
        console.error('獲取感測器列表失敗', error); // 列印錯誤資訊
        return;
      }
      this.startLightIntensityUpdates(); // 沒有錯誤則開始監聽光強度變化
    });
  }

  // 開始監聽環境光感測器的資料
  private startLightIntensityUpdates(): void {
    sensor.on(sensor.SensorId.AMBIENT_LIGHT, (data) => { // 監聽環境光感測器
      console.info(`data.intensity: ${data.intensity}`); // 列印光強度值
      this.currentIntensity = data.intensity; // 更新當前光強度值
      for (const item of this.lightIntensityList) { // 遍歷光強度列表
        if (data.intensity >= item.luxStart && data.intensity <= item.luxEnd) { // 判斷當前光強度屬於哪個範圍
          this.currentType = item.type; // 更新當前光強度型別
          break;
        }
      }
    }, { interval: 10000000 }); // 設定感測器更新間隔,單位為納秒(10000000納秒=1秒)
  }

  // 元件構建方法
  build() {
    Column() { // 建立一個垂直佈局容器
      Text("光強儀")// 顯示標題
        .width('100%')// 設定寬度為100%
        .height(44)// 設定高度為44
        .backgroundColor("#fe9900")// 設定背景顏色
        .textAlign(TextAlign.Center)// 設定文字對齊方式為中心
        .fontColor(Color.White); // 設定字型顏色為白色

      Row() { // 建立一個水平佈局容器
        Gauge({
          // 建立一個儀表元件
          value: this.currentIntensity > 1000 ? 1000 : this.currentIntensity, // 設定儀表值
          min: 0, // 最小值
          max: 1000 // 最大值
        }) { // 儀表內部佈局
          Column() { // 建立一個垂直佈局容器
            Text(`${Math.floor(this.currentIntensity)}`)// 顯示當前光強度值
              .fontSize(25)// 設定字型大小
              .fontWeight(FontWeight.Medium)// 設定字型粗細
              .fontColor("#323232")// 設定字型顏色
              .height('30%')// 設定高度為父容器的30%
              .textAlign(TextAlign.Center)// 設定文字對齊方式為中心
              .margin({ top: '22.2%' })// 設定上邊距
              .textOverflow({ overflow: TextOverflow.Ellipsis })// 設定文字溢位處理方式
              .maxLines(1); // 設定最大行數為1

            Text(`${this.currentType}`)// 顯示當前光強度型別
              .fontSize(16)// 設定字型大小
              .fontColor("#848484")// 設定字型顏色
              .fontWeight(FontWeight.Regular)// 設定字型粗細
              .width('47.4%')// 設定寬度為父容器的47.4%
              .height('15%')// 設定高度為父容器的15%
              .textAlign(TextAlign.Center)// 設定文字對齊方式為中心
              .backgroundColor("#e4e4e4")// 設定背景顏色
              .borderRadius(5); // 設定圓角半徑
          }.width('100%'); // 設定列寬度為100%
        }
        .startAngle(225) // 設定儀表起始角度
        .endAngle(135) // 設定儀表結束角度
        .height(250) // 設定儀表高度
        .strokeWidth(18) // 設定儀表邊框寬度
        .description(null) // 設定描述為null
        .trackShadow({ radius: 7, offsetX: 7, offsetY: 7 }) // 設定陰影效果
        .padding({ top: 30 }); // 設定內邊距
      }.width('100%').justifyContent(FlexAlign.Center); // 設定行寬度為100%並居中對齊

      Column() { // 建立一個垂直佈局容器
        ForEach(this.lightIntensityList, (item: LightIntensityItem, index: number) => { // 遍歷光強度型別陣列
          Row() { // 建立一個水平佈局容器
            Text(`${item.luxStart}~${item.luxEnd}Lux `)// 顯示每個型別的光強度範圍
              .fontSize('25lpx')// 設定字型大小
              .textAlign(TextAlign.Start)// 設定文字對齊方式為左對齊
              .fontColor("#3d3d3d")// 設定字型顏色
              .width('220lpx') // 設定寬度

            Text(`${item.description}\n${item.recommendation}`)// 顯示每個型別的描述和建議活動
              .fontSize('23lpx')// 設定字型大小
              .textAlign(TextAlign.Start)// 設定文字對齊方式為左對齊
              .fontColor("#3d3d3d")// 設定字型顏色
              .layoutWeight(1) // 設定佈局權重
          }.width('660lpx') // 設定行寬度
          .padding({ bottom: 10, top: 10 }) // 設定上下內邊距
          .borderWidth({ bottom: 1 }) // 設定下邊框寬度
          .borderColor("#737977"); // 設定下邊框顏色
        });
      }.width('100%'); // 設定列寬度為100%
    }
    .height('100%') // 設定容器高度為100%
    .width('100%'); // 設定容器寬度為100%
  }
}

  

相關文章