鴻蒙NEXT開發案例:血型遺傳計算

zhongcx發表於2024-11-21

【引言】

血型遺傳計算器是一個幫助使用者根據父母的血型預測子女可能的血型的應用。透過選擇父母的血型,應用程式能夠快速計算出孩子可能擁有的血型以及不可能擁有的血型。這個過程不僅涉及到了簡單的資料處理邏輯,還涉及到UI設計與互動體驗的設計。

【環境準備】

• 作業系統:Windows 10
• 開發工具:DevEco Studio NEXT Beta1 Build Version: 5.0.3.806
• 目標裝置:華為Mate60 Pro
• 開發語言:ArkTS
• 框架:ArkUI
• API版本:API 12

【開發步驟】

1. 建立元件

首先,我們使用@Entry和@Component裝飾器建立一個名為BloodTypeCalculator的元件。這標誌著我們的元件是鴻蒙NEXT應用的一個入口點。

@Entry
@Component
struct BloodTypeCalculator {
  // 元件的狀態和方法定義
}

2. 定義狀態

為了控制元件的外觀和行為,我們定義了一系列的狀態變數,如主題顏色、文字顏色、邊框顏色等。同時,我們也定義了兩個陣列來儲存可能和不可能的血型結果。

@State private themeColor: string | Color = Color.Orange;
@State private textColor: string = "#2e2e2e";
@State private lineColor: string = "#d5d5d5";
@State private possibleBloodTypesText: string = "";
@State private impossibleBloodTypesText: string = "";

3. 血型邏輯實現

接下來,實現了幾個關鍵的方法來處理血型相關的邏輯。這些方法包括根據血型獲取基因組合、組合父母的基因以獲得子代可能的基因組合、根據基因組合確定血型等。

getGenes(bloodType: string): string[];
combineGenes(fatherGenes: string[], motherGenes: string[]): string[];
getBloodTypesFromGenes(genes: string[]): string[];

4. 互動邏輯

為了實現使用者選擇父母血型後自動計運算元代血型的功能,我們使用了@Watch裝飾器監聽選擇的變化,並在變化時呼叫計算方法更新結果顯示。

@State @Watch('capsuleSelectedIndexesChanged') fatherBloodTypeIndex: number[] = [0];
@State @Watch('capsuleSelectedIndexesChanged') motherBloodTypeIndex: number[] = [0];

capsuleSelectedIndexesChanged() {
  // 更新血型資訊
}

5. UI設計

最後,我們構建了使用者介面,包括頁面標題、工具介紹、父母血型選擇區域以及結果顯示區域。這裡使用了Column、Row、Text和SegmentButton等元件來佈局和美化介面。

build() {
  Column() {
    // 頁面標題
    Text('血型遺傳計算');
    // 其他UI元素...
  }
  .height('100%')
  .width('100%')
  .backgroundColor("#f4f8fb");
}

總結

透過上述步驟,我們成功地開發了一個基於鴻蒙NEXT的血型遺傳計算器。這個案例不僅展示了鴻蒙NEXT框架下元件化開發的基本流程,同時也體現了透過合理的狀態管理和邏輯處理,可以輕鬆實現複雜的業務需求。對於希望深入瞭解鴻蒙NEXT框架的開發者來說,這是一個很好的實踐案例。希望這篇文章能為你提供靈感,鼓勵你在鴻蒙NEXT的開發道路上繼續前行。

【完整程式碼】

// 匯入SegmentButton及其相關型別定義
import { SegmentButton, SegmentButtonItemTuple, SegmentButtonOptions } from '@kit.ArkUI';

// 使用@Entry裝飾器標記此元件為入口點
@Entry
  // 使用@Component裝飾器標記此結構體為一個元件
@Component
  // 定義一個名為BloodTypeCalculator的結構體,用於實現血型遺傳計算功能
struct BloodTypeCalculator {
  // 定義主題顏色,預設為橙色
  @State private themeColor: string | Color = Color.Orange;
  // 定義文字顏色,預設為深灰色
  @State private textColor: string = "#2e2e2e";
  // 定義邊框顏色,預設為淺灰色
  @State private lineColor: string = "#d5d5d5";
  // 定義基礎內邊距大小,預設為30
  @State private basePadding: number = 30;
  // 儲存可能的血型結果
  @State private possibleBloodTypesText: string = "";
  // 儲存不可能的血型結果
  @State private impossibleBloodTypesText: string = "";
  // 定義血型列表,包含A、B、AB、O四種血型
  @State private bloodTypeList: object[] = [Object({ text: 'A' }), Object({ text: 'B' }), Object({ text: 'AB' }), Object({ text: 'O' })];
  // 初始化單選膠囊按鈕的配置項
  @State singleSelectCapsuleOptions: SegmentButtonOptions | undefined = undefined;
  // 監聽父親血型選擇變化
  @State @Watch('capsuleSelectedIndexesChanged') fatherBloodTypeIndex: number[] = [0];
  // 監聽母親血型選擇變化
  @State @Watch('capsuleSelectedIndexesChanged') motherBloodTypeIndex: number[] = [0];

  // 根據血型獲取其可能的基因組合
  getGenes(bloodType: string): string[] {
    console.info(`bloodType:${bloodType}`);
    switch (bloodType) {
      case 'A': return ['A', 'O']; // A型血可能的基因組合
      case 'B': return ['B', 'O']; // B型血可能的基因組合
      case 'AB': return ['A', 'B']; // AB型血可能的基因組合
      case 'O': return ['O']; // O型血可能的基因組合
      default: throw new Error('Invalid blood type'); // 非法血型丟擲錯誤
    }
  }

  // 組合父母的基因以獲得子代可能的基因組合
  combineGenes(fatherGenes: string[], motherGenes: string[]): string[] {
    const possibleGenes: string[] = []; // 用於儲存可能的基因組合
    for (const fatherGene of fatherGenes) {
      for (const motherGene of motherGenes) {
        const combinedGene = [fatherGene, motherGene].sort().join(''); // 將父母的基因組合並排序後加入陣列
        if (!possibleGenes.includes(combinedGene)) {
          possibleGenes.push(combinedGene); // 如果組合尚未存在,則加入陣列
        }
      }
    }
    return possibleGenes; // 返回所有可能的基因組合
  }

  // 根據基因組合確定血型
  getBloodTypesFromGenes(genes: string[]): string[] {
    const bloodTypes: string[] = []; // 用於儲存可能的血型
    for (const gene of genes) {
      if (gene === 'AA' || gene === 'AO' || gene === 'OA') {
        bloodTypes.push('A'); // 基因組合為AA、AO或OA時,血型為A
      } else if (gene === 'BB' || gene === 'BO' || gene === 'OB') {
        bloodTypes.push('B'); // 基因組合為BB、BO或OB時,血型為B
      } else if (gene === 'AB' || gene === 'BA') {
        bloodTypes.push('AB'); // 基因組合為AB或BA時,血型為AB
      } else if (gene === 'OO') {
        bloodTypes.push('O'); // 基因組合為OO時,血型為O
      }
    }
    // 去除重複的血型
    return bloodTypes.filter((value, index, self) => self.indexOf(value) === index);
  }

  // 計算孩子可能的血型及不可能的血型
  calculatePossibleBloodTypes(father: string, mother: string) {
    const fatherGenes = this.getGenes(father); // 獲取父親的基因組合
    const motherGenes = this.getGenes(mother); // 獲取母親的基因組合
    const possibleGenes = this.combineGenes(fatherGenes, motherGenes); // 組合父母的基因
    const possibleBloodTypes = this.getBloodTypesFromGenes(possibleGenes); // 從基因組合中獲取可能的血型
    const allBloodTypes: string[] = ['A', 'B', 'AB', 'O']; // 所有可能的血型列表
    const impossibleBloodTypes = allBloodTypes.filter(bt => !possibleBloodTypes.includes(bt)); // 計算不可能的血型
    console.log(this.possibleBloodTypesText = `孩子可能血型:${possibleBloodTypes.join('、')}`); // 顯示可能的血型
    console.log(this.impossibleBloodTypesText = `孩子不可能血型:${impossibleBloodTypes.join('、')}`); // 顯示不可能的血型
  }

  // 當膠囊按鈕的選擇發生變化時呼叫此函式
  capsuleSelectedIndexesChanged() {
    let father: string = this.bloodTypeList[this.fatherBloodTypeIndex[0]]['text']; // 獲取父親選擇的血型
    let mother: string = this.bloodTypeList[this.motherBloodTypeIndex[0]]['text']; // 獲取母親選擇的血型
    this.calculatePossibleBloodTypes(father, mother); // 計算並更新血型資訊
  }

  // 在元件即將出現時呼叫此函式
  aboutToAppear(): void {
    this.singleSelectCapsuleOptions = SegmentButtonOptions.capsule({
      buttons: this.bloodTypeList as SegmentButtonItemTuple, // 設定膠囊按鈕的選項
      multiply: false, // 單選模式
      fontColor: Color.White, // 字型顏色為白色
      selectedFontColor: Color.White, // 選中時字型顏色為白色
      selectedBackgroundColor: this.themeColor, // 選中背景色為主題色
      backgroundColor: this.lineColor, // 背景色為邊框顏色
      backgroundBlurStyle: BlurStyle.BACKGROUND_THICK // 背景模糊效果
    });
    this.capsuleSelectedIndexesChanged(); // 初始化時呼叫選擇變化處理函式
  }

  // 構建使用者介面
  build() {
    Column() {
      // 頁面標題
      Text('血型遺傳計算')
        .fontColor(this.textColor) // 文字顏色
        .fontSize(18) // 字型大小
        .width('100%') // 寬度為100%
        .height(50) // 高度為50
        .textAlign(TextAlign.Center) // 文字居中對齊
        .backgroundColor(Color.White) // 背景色為白色
        .shadow({ // 新增陰影效果
          radius: 2, // 陰影半徑
          color: this.lineColor, // 陰影顏色
          offsetX: 0, // 水平偏移量
          offsetY: 5 // 垂直偏移量
        });

      // 工具介紹部分
      Column() {
        Text('工具介紹').fontSize(20).fontWeight(600).fontColor(this.textColor);
        Text('血型是以A、B、O三種遺傳因子的組合而決定的,根據父母的血型,就可以判斷出以後出生的孩子的血型。')
          .fontSize(18).fontColor(this.textColor).margin({ top: `${this.basePadding / 2}lpx` });
      }
      .alignItems(HorizontalAlign.Start)
      .width('650lpx')
      .padding(`${this.basePadding}lpx`)
      .margin({ top: `${this.basePadding}lpx` })
      .borderRadius(10)
      .backgroundColor(Color.White)
      .shadow({
        radius: 10,
        color: this.lineColor,
        offsetX: 0,
        offsetY: 0
      });

      // 父親血型選擇部分
      Column() {
        Row() {
          Text('父親血型').fontColor(this.textColor).fontSize(18);
          SegmentButton({
            options: this.singleSelectCapsuleOptions, // 膠囊按鈕的配置項
            selectedIndexes: this.fatherBloodTypeIndex // 當前選中的索引
          }).width('400lpx');
        }.height(45).justifyContent(FlexAlign.SpaceBetween).width('100%');

        // 母親血型選擇部分
        Row() {
          Text('母親血型').fontColor(this.textColor).fontSize(18);
          SegmentButton({
            options: this.singleSelectCapsuleOptions, // 膠囊按鈕的配置項
            selectedIndexes: this.motherBloodTypeIndex // 當前選中的索引
          }).width('400lpx');
        }.height(45).justifyContent(FlexAlign.SpaceBetween).width('100%');
      }
      .alignItems(HorizontalAlign.Start)
      .width('650lpx')
      .padding(`${this.basePadding}lpx`)
      .margin({ top: `${this.basePadding}lpx` })
      .borderRadius(10)
      .backgroundColor(Color.White)
      .shadow({
        radius: 10,
        color: this.lineColor,
        offsetX: 0,
        offsetY: 0
      });

      // 顯示計算結果
      Column() {
        Row() {
          Text(this.possibleBloodTypesText).fontColor(this.textColor).fontSize(18);
        }.height(45).justifyContent(FlexAlign.SpaceBetween).width('100%');
        Row() {
          Text(this.impossibleBloodTypesText).fontColor(this.textColor).fontSize(18);
        }.height(45).justifyContent(FlexAlign.SpaceBetween).width('100%');
      }
      .alignItems(HorizontalAlign.Start)
      .width('650lpx')
      .padding(`${this.basePadding}lpx`)
      .margin({ top: `${this.basePadding}lpx` })
      .borderRadius(10)
      .backgroundColor(Color.White)
      .shadow({
        radius: 10,
        color: this.lineColor,
        offsetX: 0,
        offsetY: 0
      });
    }
    .height('100%')
    .width('100%')
    .backgroundColor("#f4f8fb"); // 頁面背景色
  }
}

  

相關文章