iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0
Mobile Development

攜手神隊友ChatGPT:攝護腺自我照護App開發歷程!系列 第 16

D16-Flutter x Dart視覺化魔法,攝護腺量表走勢圖_part3

  • 分享至 

  • xImage
  •  

Part1:今日目標

1.前言
2.Flutter x Dart 學習
3.結語

Part2:今日內容

1.前言

今天將根據昨天鐵人賽文章 D15-Flutter x Dart視覺化魔法,攝護腺量表走勢圖_part2 的內容做詳細的說明,所討論的內容都是在實作過程有的疑惑,透過這些問答期望能幫助自己還有大家對整個程式碼內容有更好的掌握。今日文章順序與昨天提供的程式碼相同,將依序介紹class ScoreHistoryChartPage extends StatefulWidget {}class _ScoreHistoryChartPageState extends State<ScoreHistoryChartPage> {},讓我們開始吧!

2.Flutter x Dart 學習

(1)class ScoreHistoryChartPage extends StatefulWidget {}

class ScoreHistoryChartPage extends StatefulWidget {
  // ScoreHistoryChartPage 是一個繼承自 StatefulWidget 的類別: 表示這是一個具有內部狀態的 widget

  // 用於存儲分數歷史數據的 FlSpot 列表,FlSpot 是用於 fl_chart 庫的類別,表示圖表中的一個數據點
  final List<FlSpot> data;
  final List<String> dates;  // 存儲每個數據點相對應的日期的列表

  // 這個 widget的構造函式,接收數據和日期作為必要的參數
  ScoreHistoryChartPage({required this.data, required this.dates});

  @override
  // _ScoreHistoryChartPageState 是 ScoreHistoryChartPage 的內部狀態類別: 該狀態類別負責實現該 widget的具體 UI 和功能
  _ScoreHistoryChartPageState createState() => _ScoreHistoryChartPageState();
}

Q1: final 為何不能放在 class _ScoreHistoryChartPageState extends State {} 裡面,要放在 class ScoreHistoryChartPage extends StatefulWidget {} 裡面?

Ans: 在 Flutter 中,通常會將 widget 的配置參數(例如 data 和 dates)定義為 widget 類別(例如 ScoreHistoryChartPage)的成員變數,而不是放在該 widget 的內部狀態(_ScoreHistoryChartPageState)中。這是因為這些配置參數通常是由外部傳遞給 widget 的,而不是在 widget 的狀態中管理的。

在 Dart 中,final 關鍵字用於聲明一個不可變的變數,這代表一旦賦值後,它的值不能再被修改。在我們的程式碼中,final 關鍵字被用來聲明 data 和 dates 兩個成員變數,這是一個常見的做法,尤其是當這些變數的值需要在整個類別中被存取和使用時。

final 變數不一定要放在 class 內部,但根據通常的程式設計風格和最佳實踐,將這些成員變數定義為 class 的一部分是合理的。這樣做的好處包括:

  • 封裝性: 將這些變數作為 class 的成員變數,可以確保它們只在該 class 內可見,從而實現了封裝性。這使得它們不容易被外部誤用或修改。

  • 可重用性: 如果你將這個 widget 用於多個地方,將這些變數放在 class 內部可以確保它們在每個使用該 widget 的地方都是可用的。

  • 可配置性:將配置參數作為 widget 的構造函式參數,使得你可以在每次使用該 widget 時,根據需要提供不同的數據和日期,從而增強了 widget 的可配置性。

  • 可讀性和可維護性:將配置參數放在 widget 類別中,可以讓其他開發人員更容易理解這個 widget 的作用和所需的輸入。這樣的設計也使得代碼更具可讀性,因為 widget 的用途和所需的數據是明確可見的。

Q2: 以下這段程式碼的 應該如何理解?

final List<FlSpot> data;

Ans: final List data; 中的 是通用型別(Generic)參數的一部分,它指定了 data 變數的類型。通用型別允許開發者在聲明變數、類別或函式時,指定一個通用的類型,以便在後續使用時,根據實際需要提供具體的類型。

在這個情境中,data 變數被聲明為 List,這表示它是一個列表,其中的每個元素都應該是 FlSpot 類型的對象。簡單來說,data 變數應該存儲一個 FlSpot 對象的列表。

來自於 import 'package:fl_chart/fl_chart.dart';,這個 import 語句將 fl_chart 庫中的相關類別引入到 Dart 文件中,包括 FlSpot 類別。

FlSpot 代表圖表中的數據點,包括 x 和 y 座標。所以 data 變數預期包含一組 FlSpot 對象,用於在圖表上顯示數據的數據點。

使用通用型別可以提供類型安全性,確保變數只包含指定類型的對象,同時提供更好的程式碼設計和可讀性。

Q3: 承上,關於通用型別定義和用法?

Ans: 當我們設計程式時,經常會遇到需要處理不同類型數據的情況。通常情況下,我們需要為每種不同的數據類型編寫不同的程式碼。通用型別(Generics)是一種程式語言功能,它讓我們可以創建更具靈活性和通用性的程式碼,無需針對不同類型的數據重複編寫程式碼。以下是通用型別的更詳細解釋:

  • 為什麼需要通用型別?
    假你正在設計一個儲存盒(Box)的程式,盒子可以存放不同類型的物品,例如整數、字符串、浮點數等。如果不使用通用型別,需要為每種類型的盒子編寫不同的程式碼:

    class IntBox {
      int value;
      IntBox(this.value);
    }
    
    class StringBox {
      String value;
      StringBox(this.value);
    }
    
    // ...其他盒子類別
    
    

    但使用通用型別,可以創建一個通用的盒子類別,處理各種類型的物品,無需為每種類型重複編寫程式碼。

  • 通用型別的定義:
    通用型別的定義使用 < > 符號,並在定義變數、函式或類別時指定一個通用的型別參數,通常表示為單個大寫字母,例如 <T>

    class Box<T> {
      T value;
      Box(this.value);
    }
    

    在這個例子中, 表示通用型別參數,Box 類別接受一個型別為 T 的值。

  • 通用型別的使用:
    通用型別可以在實例化物件或呼叫函式時提供具體的型別。例如,如果要創建一個整數盒子,可以這樣做:

    var intBox = Box<int>(42);
    

    這裡,Box<int> 代表我們要創建一個整數盒子,並將 42 作為值放入該盒子中。

  • 通用型別函式:
    通用型別不僅可以應用於類別,還可以應用於函式。例如,我們可以創建一個通用的函式,用於返回傳入值的相同型別:

    T identity<T>(T value) {
      return value;
    }
    
    var intValue = identity<int>(42);
    var stringValue = identity<String>('Hello');
    

    在這個例子中,identity 函式接受一個值和一個通用型別參數 T,然後返回該值。通過提供 <int><String>,我們可以告訴函式返回相應的型別。

Q4: 以下 createState() 定義和用法為何?

_ScoreHistoryChartPageState createState() => _ScoreHistoryChartPageState();

Ans: createState() 方法是在 Flutter 中用於建立一個新的狀態對象的工廠方法。這個方法通常在 StatefulWidget 的子類中實現,並且必須返回一個對應的狀態對象。

  • _ScoreHistoryChartPageState 是一個自定義的狀態(State)類別,它是 _ScoreHistoryChartPageStatefulWidget(或其他 StatefulWidget 的子類別)的內部狀態。每當與 ScoreHistoryChartPage 這個 widget 相關聯的狀態需要創建時,createState() 方法就會被調用,並返回一個新的 _ScoreHistoryChartPageState 物件。

  • => 符號是一種簡潔的 Dart 語法,它表示立即返回右側的表達式結果。在這個情境下,createState() 方法立即返回一個新的 _ScoreHistoryChartPageState 物件,而不需要使用額外的 return 關鍵字。

  • _ScoreHistoryChartPageState() 構造函式用於創建 _ScoreHistoryChartPageState 物件的新實例,這個實例將成為與 ScoreHistoryChartPage widget 相關聯的狀態。

3.結語

關於另一個類別 class _ScoreHistoryChartPageState extends State<ScoreHistoryChartPage> {} 的學習內容,將會接續在明天進行介紹。

一個成功的領導者,三個因素,眼光、胸懷和實力
A successful leader has three factors, vision, magnanimity, and capability.
聽了一些荒唐事,讓我不禁覺得金錢和道德宛如天秤的兩端,存在著微妙的衝突關係


上一篇
D15-Flutter x Dart視覺化魔法,攝護腺量表走勢圖_part2
下一篇
D17-Flutter x Dart視覺化魔法,攝護腺量表走勢圖_part4
系列文
攜手神隊友ChatGPT:攝護腺自我照護App開發歷程!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言