Finish Flutter heading
This commit is contained in:
+170
-675
@@ -2,6 +2,7 @@
|
||||
#import "@preview/treet:1.0.0": *
|
||||
#import "@preview/tiaoma:0.3.0"
|
||||
#set heading(numbering: "1.1", offset: 1)
|
||||
#set figure(kind: image)
|
||||
|
||||
= Flutter <flutter>
|
||||
|
||||
@@ -19,731 +20,225 @@ Alibaba
|
||||
ช่วยลดความยุ่งยากในการรองรับหลายแพลตฟอร์ม เนื่องจากสามารถใช้โคด UI
|
||||
ที่เหมือนกันได้กับทุกแพลตฟอร์มเป้าหมาย
|
||||
|
||||
== การติดตั้งโปรแกรมเขียนโคด
|
||||
|
||||
#i จริง ๆ แล้วนั้น Flutter สามารถทำงานกับโปรแกรมเขียนโคดใดก็ได้
|
||||
แต่มีโปรแกรมเหล่านี้ที่อาจมีประสบการณ์การพัฒนาที่ดีกว่าโปรแกรมอื่น:
|
||||
|
||||
- Visual Studio Code (VS Code)
|
||||
- Android Studio
|
||||
- JetBrains IntelliJ
|
||||
- Firebase Studio
|
||||
|
||||
#i โครงงานนี้ใช้โปรแกรมเขียนโคด Android Studio เป็นหลักเนื่องจากแอพลิเคชันโครงงานมี Android
|
||||
เป็นเป้าหมายหลัก และ Android SDK สามารถจัดการได้ง่ายกว่าใน Android Studio
|
||||
|
||||
=== Android Studio
|
||||
|
||||
#i Android Studio สามารถดาวน์โหลดได้ผ่าน https://developer.android.com/studio
|
||||
หรือสามารถถูกติดตั้งและจัดการผ่านแอพลิเคชัน JetBrains Toolbox ได้เช่นกัน
|
||||
(https://www.jetbrains.com/toolbox-app/)
|
||||
|
||||
== การติดตั้ง Flutter <flInstall>
|
||||
|
||||
#i การติดตั้ง Flutter สามารถทำได้สองวิธีด้วยกัน คือการติดตั้งผ่าน Visual Studio Code (VS
|
||||
Code) และการติดตั้งด้วยตนเอง โดยหากต้องการใช้ VS Code เป็นโปรแกรมเขียนโคดอยู่แล้ว
|
||||
สามารถติดตั้งผ่าน VS Code ได้เลย
|
||||
|
||||
#i แต่ก่อนอื่น ต้องทำการติดตั้งโปรแกรมและไลบรารีพื้นฐานที่จำเป็นสำหรับ Flutter ก่อน
|
||||
|
||||
=== การติดตั้งโปรแกรมและไลบรารีที่จำเป็น
|
||||
|
||||
==== Windows
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
column-gutter: 1em,
|
||||
[#i ในการพัฒนาซอฟต์แวร์บน Windows ด้วย Flutter คุณจำเป็นต้องติดตั้ง Git สำหรับ Windows
|
||||
ซึ่งคุณสามารถดูขั้นตอนการติดตั้งได้โดยการสแกน QR code ด้านข้าง หรือที่
|
||||
https://git-scm.com/install/windows หรือเพียงแค่ใช้ WinGet
|
||||
ในการติดตั้งโดยการใช้คำสั่งด้านล่าง],
|
||||
tiaoma.qrcode(
|
||||
"https://git-scm.com/install/windows",
|
||||
width: 1in,
|
||||
alt: "QR โคดสำหรับหน้าการติดตั้ง Git สำหรับ Windows",
|
||||
),
|
||||
)
|
||||
|
||||
```sh
|
||||
winget install --id Git.Git -e --source winget
|
||||
```
|
||||
|
||||
==== Linux
|
||||
|
||||
#i Flutter ใช้ไลบรารีดังต่อไปนี้ในขั้นตอนการพัฒนาแอพลิเคชันบน Linux (development
|
||||
dependencies; ยังไม่รวมไลบรารีและโปรแกรมที่ต้องมีในการสร้างแอพลิเคชัน _สำหรับ_ Linux)
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
column-gutter: 2in,
|
||||
[
|
||||
- curl
|
||||
- git
|
||||
- unzip
|
||||
],
|
||||
[
|
||||
- xz
|
||||
- zip
|
||||
- glu
|
||||
],
|
||||
)
|
||||
|
||||
หากต้องการคำสั่งในการติดตั้งแพคเกจเหล่านี้ โปรดดู@flLinuxDetails
|
||||
|
||||
==== macOS
|
||||
|
||||
#i จำเป็นต้องทำการติดตั้งเครื่องมือ command-line Xcode เพื่อเข้าถึงเครื่องมือที่ Flutter
|
||||
จำเป็นต้องใช้ รวมถึง Git
|
||||
|
||||
ในการดาวน์โหลดเครื่องมือ ใช้คำสั่งต่อไปนี้ในเทอร์มินัลที่คุณเลือก:
|
||||
|
||||
```sh
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
#i หากคุณไม่ได้ติดตั้งเครื่องมืออยู่แล้ว จะมีไดอะลอกเพื่อคอนเฟิร์มว่าคุณต้องการที่จะติดตั้งมัน กด
|
||||
*Install* และกด *Done* เมื่อทำการติดตั้งเสร็จสิ้นแล้ว
|
||||
|
||||
#pagebreak()
|
||||
|
||||
=== การติดตั้งผ่าน Visual Studio Code
|
||||
|
||||
#[
|
||||
#set enum(indent: 3em)
|
||||
+ เปิด VSCode
|
||||
+ ติดตั้งส่วนขยาย Flutter \
|
||||
อยู่ภายใต้ ID `Dart-Code.flutter` ทั้งบน Visual Studio Marketplace และ OpenVSX
|
||||
+ ติดตั้ง Flutter ด้วย VS Code
|
||||
+ เปิด Command Palette ด้วยเมนู *View* > *Command Palette* หรือกด Ctrl + Shift +
|
||||
P
|
||||
+ ใน Command Palette พิมพ์ `flutter`.
|
||||
+ เลือก *Flutter: New Project*
|
||||
+ VS Code จะให้คุณเลือก Flutter SDK บนคอมพิวเตอร์ของคุณ เลือก *Download SDK*
|
||||
+ เมือหน้าไดอะลอก *Select Folder for Flutter SDK* แสดงขึ้น เลือกสถานที่ที่คุณอยากติดตั้ง
|
||||
Flutter
|
||||
+ คลิก *Clone Flutter* \
|
||||
ในระหว่างการดาวน์โหลด VS Code จะแสดงการแจ้งเตือนนี้:
|
||||
```
|
||||
Downloading the Flutter SDK. This may take a few minutes.
|
||||
```
|
||||
การดาวน์โหลดนี้จะใช้เวลาสองสามนาที หากคุณเชื่อว่าการดาวน์โหลดหยุดชะงัก คุณสามารถคลิก
|
||||
*Cancel* แล้วเริ่มต้นการติดตั้งใหม่ได้
|
||||
+ คลิก *Add SDK to PATH* \
|
||||
เมื่อเสร็จสิ้น จะมีการแจ้งเตือน
|
||||
```
|
||||
The Flutter SDK was added to your PATH
|
||||
```
|
||||
+ VS Code อาจแสดงการแจ้งเตือนเกี่ยวกับการเก็บข้อมูลของ Google หากคุณยินยอม คลิก *OK*
|
||||
+ เพื่อความแน่ใจ กรุณาปิดเทอร์มินัลทุกหน้าต่างหรือรีสตาร์ท VS Code เพื่อให้แน่ใจว่า Flutter
|
||||
จะสามารถใช้ผ่านเทอร์มินัลได้
|
||||
+ เมื่อเสร็จสิ้น ใช้คำสั่ง `flutter doctor -v` ในเทอร์มินัลที่คุณเลือกเพื่อตรวจสอบการติดตั้ง
|
||||
Flutter ของคุณ \
|
||||
หากคำสั่งไม่เจอหรือเกิดข้อผิดพลาดขึ้น ตรวจสอบ
|
||||
https://docs.flutter.dev/install/troubleshoot สำหรับข้อมูลเพิ่มเติม
|
||||
]
|
||||
|
||||
=== การติดตั้งด้วยตนเอง
|
||||
|
||||
#i แนะนำให้ทำตาม https://docs.flutter.dev/install/manual#install-flutter
|
||||
เนื่องจากกระบวนการนี้ต้องใช้ข้อมูลที่ใหม่ล่าสุด
|
||||
|
||||
1. ดาวน์โหลด Flutter (สามารถหาปุ่มดาวน์โหลดได้จากลิงก์ด้านบน)
|
||||
2. สร้างโฟลเดอร์สำหรับเก็บ Flutter SDK
|
||||
3. ทำการแตกไฟล์ที่ดาวน์โหลดมา
|
||||
4. เพิ่ม Flutter เข้าไปยัง PATH ของคุณ (วิธีการขึ้นอยู่กับระบบปฏิบัติการ)
|
||||
5. ยืนยันความถูกต้องของการติดตั้งของคุณด้วยคำสั่ง `flutter doctor -v`
|
||||
|
||||
== Dart
|
||||
|
||||
#i Dart เป็นภาษาโปรแกรมที่ออกแบบโดย Lars Bak และ Kasper Lund และพัฒนาโดย Google
|
||||
#iii Dart เป็นภาษาโปรแกรมที่ออกแบบโดย Lars Bak และ Kasper Lund และพัฒนาโดย Google
|
||||
สามารถใช้พัฒนาแอปพลิเคชันบนเว็บ มือถือ เซิร์ฟเวอร์ และเดสก์ท็อปได้
|
||||
และยังเป็นภาษาหลักที่ใช้ในการพัฒนาแอพลิเคชัน Flutter
|
||||
และยังเป็นภาษาหลักที่ใช้ในการพัฒนาแอปพลิเคชัน Flutter
|
||||
|
||||
#i Dart เป็นภาษาเชิงวัตถุ อิงคลาส และรวบรวมขยะ (garbage-collection) ด้วยไวยากรณ์แบบ C
|
||||
#iii Dart เป็นภาษาเชิงวัตถุ อิงคลาส และรวบรวมขยะ (garbage-collection) ด้วยไวยากรณ์แบบ C
|
||||
สามารถคอมไพล์เป็นโค้ดเครื่อง JavaScript หรือ WebAssembly ได้ รองรับอินเทอร์เฟซ มิกซ์อิน
|
||||
คลาสนามธรรม เจเนอริกแบบรีไฟด์ และการอนุมานชนิดข้อมูล
|
||||
|
||||
== การสร้างโปรเจกต์
|
||||
#pagebreak()
|
||||
|
||||
#i ตั้งแต่หัวข้อนี้เป็นต้นไป จะเป็นข้อมูลสำหรับการทำงานกับ Android Studio
|
||||
เป็นหลักเนื่องจากเป็นโปรแกรมหลักที่ถูกใช้งานในการพัฒนาแอพลิเคชันโครงงานนี้
|
||||
== สถาปัตยกรรม
|
||||
|
||||
#i หากยังไม่ได้ติดตั้งปลั๊กอิน Flutter โปรดติดตั้งปลั๊กอินก่อน โดยหากอยู่ในหน้าต้อนรับ
|
||||
สามารถติดตั้งปลั๊กอินได้โดยการเข้าไปยังแท็บ *Plugins* หรือหากเปิดโปรเจกต์อื่นอยู่
|
||||
สามารถเข้าถึงหน้าปลั๊กอินได้โดยการกดที่ไอคอนฟันเฟืองในแถบเครื่องมือ แล้วกด *Plugins...*
|
||||
หลังจากนั้น ในแท็บ *Marketplace* ของหน้าปลั๊กอิน ค้นหา *Flutter* (ผู้ผลิตปลั๊กอินคือ Google)
|
||||
แล้วกด *Install*
|
||||
#iii Flutter ถูกออกแบบมาให้เป็นระบบแบบเลเยอร์ที่ต่อขยายได้
|
||||
ประกอบด้วยไลบรารีอิสระหลายชุดที่แต่ละชุดพึ่งพาเลเยอร์ที่อยู่ด้านล่าง
|
||||
ไม่มีเลเยอร์ใดที่มีสิทธิ์พิเศษในการเข้าถึงเลเยอร์ด้านล่าง
|
||||
และทุกส่วนของเฟรมเวิร์กถูกออกแบบมาให้เป็นตัวเลือกและสามารถทดแทนได้
|
||||
|
||||
#afigure(
|
||||
image("Flutter/homePage.png", width: 65%),
|
||||
alt: "หน้ายินดีต้อนรับในแท็บ Projects ที่กำลังแสดงรายการโปรเจกต์และปุ่มในการสร้างโปรเจกต์ใหม่",
|
||||
caption: [หน้ายินดีต้อนรับใน Android Studio],
|
||||
image("Flutter/archdiagram.png", width: 80%),
|
||||
attr: [Flutter, ภายใต้ CC BY 4.0],
|
||||
alt: "แผนผังสถาปัตยกรรม Flutter",
|
||||
caption: [สถาปัตยกรรม Flutter],
|
||||
)
|
||||
|
||||
#i เมื่อคลิก *New Flutter Project* จะมีหน้าถามสถานที่ติดตั้ง Flutter SDK หลังจากนั้น กด
|
||||
*Next* แล้วจะมีหน้าต่อไปนี้ขึ้นมาเพื่อให้คุณกรอกรายละเอียดโปรเจกต์
|
||||
#iii สำหรับระบบปฏิบัติการที่อยู่ภายใต้ แอปพลิเคชัน Flutter
|
||||
จะถูกบรรจุในลักษณะเดียวกับแอปพลิเคชันเนทีฟอื่น ๆ โดยตัวฝังตัว (Embedder)
|
||||
เฉพาะแพลตฟอร์มจะทำหน้าที่เป็นจุดเริ่มต้น ประสานงานกับระบบปฏิบัติการที่อยู่ภายใต้เพื่อเข้าถึงบริการต่างๆ
|
||||
เช่น พื้นผิวการแสดงผล การเข้าถึง และการป้อนข้อมูล และจัดการลูปเหตุการณ์ข้อความ
|
||||
ตัวฝังตัวเขียนด้วยภาษาที่เหมาะสมกับแพลตฟอร์ม ปัจจุบันคือ Java และ C++ สำหรับ Android, Swift
|
||||
และ Objective-C/Objective-C++ สำหรับ#jb iOS และ macOS และ C++ สำหรับ Windows และ
|
||||
Linux การใช้ตัวฝังตัว โค้ด Flutter สามารถรวมเข้ากับแอปพลิเคชันที่มีอยู่แล้วในรูปแบบโมดูล
|
||||
หรือโค้ดอาจเป็นเนื้อหาทั้งหมดของแอปพลิเคชันก็ได้ Flutter
|
||||
มีตัวฝังตัวจำนวนมากสำหรับแพลตฟอร์มเป้าหมายทั่วไป แต่ก็ยังมีตัวฝังตัวอื่นๆ อีกด้วย
|
||||
|
||||
#afigure(
|
||||
image("Flutter/newProjectPage.png", width: 80%),
|
||||
alt: "หน้ากรอกรายละเอียดโปรเจกต์ใหม่",
|
||||
caption: [หน้าโปรเจกต์ใหม่],
|
||||
)
|
||||
#iii หัวใจหลักของ Flutter คือ Flutter engine ซึ่งส่วนใหญ่เขียนด้วยภาษา C++
|
||||
และรองรับฟังก์ชันพื้นฐานที่จำเป็นต่อการทำงานของแอปพลิเคชัน Flutter ทั้งหมด
|
||||
เอนจินนี้มีหน้าที่ในการแปลงฉากที่ประกอบขึ้นเป็นภาพแรสเตอร์ทุกครั้งที่จำเป็นต้องวาดเฟรมใหม่
|
||||
มันมีหน้าที่ให้การใช้งานระดับต่ำของ API หลักของ Flutter รวมถึงการจัดวางข้อความกราฟิก
|
||||
การรับส่งข้อมูลไฟล์และเครือข่าย รันไทม์ Dart และเครื่องมือคอมไพล์
|
||||
|
||||
รายละเอียดที่จำเป็นต้องกรอกในการสร้างโปรเจกต์ใหม่มีดังนี้:
|
||||
#iii เอนจินนี้ถูกเปิดเผยสู่เฟรมเวิร์ก Flutter ผ่านทาง dart:ui ซึ่งห่อหุ้มโค้ด C++
|
||||
ที่อยู่เบื้องหลังด้วยคลาส Dart ไลบรารีนี้เปิดเผยส่วนประกอบพื้นฐานระดับต่ำสุด เช่น
|
||||
คลาสสำหรับควบคุมระบบย่อยการรับข้อมูล กราฟิก และการแสดงผลข้อความ
|
||||
|
||||
- *Project name:* ชื่อโปรเจกต์
|
||||
- *Project location:* โฟลเดอร์ที่ต้องการเก็บโปรเจกต์
|
||||
- *Description:* รายละเอียดโปรเจกต์
|
||||
- *Project type:* ประเภทโปรเจกต์ ในกรณีนี้เป็นค่า *Application*
|
||||
เนื่องจากเราต้องการสร้างแอพลิเคชัน
|
||||
- *Organization:* โดเมนเนมย้อนหลังขององค์กรที่พัฒนา (Reverse domain name notation;
|
||||
Reverse-DNS)
|
||||
- *Android language:* เลือกระหว่าง Java และ Kotlin เป็นภาษาหลักที่ใช้ในแอพลิเคชัน Android
|
||||
- *Platforms:* แพลตฟอร์มที่โปรเจกต์จะรองรับ อย่างไรก็ตาม
|
||||
การสร้างไฟล์ไบนารีสำหรับแอพลิเคชันขึ้นอยู่กับแพลตฟอร์มที่พัฒนาแอพลิเคชันเช่นกัน หมายความว่า
|
||||
ถึงแม้ตามทฤษฎีแล้วแอพลิเคชันของคุณจะรองรับ iOS คุณต้องมีอุปกรณ์ Mac ในการสร้างไฟล์แอพลิเคชัน
|
||||
iOS ออกมา
|
||||
#iii โดยทั่วไป นักพัฒนาจะโต้ตอบกับ Flutter ผ่านเฟรมเวิร์ก Flutter
|
||||
ซึ่งเป็นเฟรมเวิร์กที่ทันสมัยและตอบสนองต่อสิ่งรอบข้าง เขียนด้วยภาษา Dart
|
||||
เฟรมเวิร์กนี้ประกอบด้วยชุดไลบรารีแพลตฟอร์ม เลย์เอาต์ และพื้นฐานที่ครบครัน
|
||||
ซึ่งประกอบด้วยเลเยอร์หลายชั้น เริ่มจากล่างขึ้นบน ได้แก่:
|
||||
|
||||
เมื่อทำการใส่รายละเอียดทั้งหมดแล้ว สามารถกด Create เพื่อสร้างโปรเจกต์ได้เลย
|
||||
- คลาสพื้นฐานและบริการส่วนประกอบต่างๆ เช่น แอนิเมชัน การวาดภาพ และท่าทางสัมผัส
|
||||
ซึ่งนำเสนอนามธรรมที่ใช้กันทั่วไปเหนือพื้นฐานที่อยู่เบื้องหลัง
|
||||
|
||||
- เลเยอร์การเรนเดอร์ให้นามธรรมสำหรับการจัดการเลย์เอาต์ ด้วยเลเยอร์นี้
|
||||
คุณสามารถสร้างโครงสร้างแบบต้นไม้ของวัตถุที่เรนเดอร์ได้ คุณสามารถจัดการวัตถุเหล่านี้แบบไดนามิก
|
||||
โดยโครงสร้างแบบต้นไม้จะอัปเดตเลย์เอาต์โดยอัตโนมัติเพื่อสะท้อนการเปลี่ยนแปลงของคุณ
|
||||
|
||||
- เลเยอร์วิดเจ็ตเป็นนามธรรมของการประกอบ
|
||||
วัตถุเรนเดอร์แต่ละชิ้นในเลเยอร์การเรนเดอร์จะมีคลาสที่สอดคล้องกันในเลเยอร์วิดเจ็ต นอกจากนี้
|
||||
เลเยอร์วิดเจ็ตยังช่วยให้คุณกำหนดการรวมกันของคลาสที่คุณสามารถนำกลับมาใช้ใหม่ได้
|
||||
นี่คือเลเยอร์ที่แนะนำโมเดลการเขียนโปรแกรมแบบตอบสนอง
|
||||
|
||||
- ไลบรารี Material และ Cupertino
|
||||
นำเสนอชุดควบคุมที่ครอบคลุมซึ่งใช้ส่วนประกอบพื้นฐานของเลเยอร์วิดเจ็ตเพื่อนำภาษาการออกแบบ
|
||||
Material หรือ iOS ไปใช้
|
||||
|
||||
#iii เฟรมเวิร์ก Flutter มีขนาดค่อนข้างเล็ก
|
||||
ฟีเจอร์ระดับสูงหลายอย่างที่นักพัฒนาอาจใช้ถูกพัฒนาขึ้นมาในรูปแบบของแพ็กเกจ
|
||||
รวมถึงปลั๊กอินของแต่ละแพลตฟอร์ม เช่น กล้องและเว็บวิว ตลอดจนฟีเจอร์ที่ไม่ขึ้นกับแพลตฟอร์ม เช่น
|
||||
ตัวอักษร, HTTP และแอนิเมชัน ซึ่งสร้างขึ้นจากไลบรารีหลักของ Dart และ Flutter
|
||||
แพ็กเกจบางส่วนมาจากระบบนิเวศที่กว้างกว่า ครอบคลุมบริการต่างๆ เช่น การชำระเงินภายในแอป
|
||||
การตรวจสอบสิทธิ์ของ Apple และแอนิเมชัน
|
||||
|
||||
#pagebreak()
|
||||
|
||||
== แอพลิเคชันตัวอย่าง
|
||||
== โครงสร้างของแอปพลิเคชัน
|
||||
|
||||
เมื่อกดรันแอพลิเคชันด้วยไอคอน #box(
|
||||
image("Flutter/vscode_play.svg", alt: "Play"),
|
||||
baseline: 15%,
|
||||
) (หรือ Shift+F10 ใน Android Studio) จะได้แอพลิเคชันดังรูปด้านล่างออกมา
|
||||
#iii แผนภาพต่อไปนี้แสดงภาพรวมของส่วนประกอบต่างๆ ที่ประกอบกันเป็นแอป Flutter
|
||||
ทั่วไปที่สร้างขึ้นโดยคำสั่ง `flutter create` แผนภาพนี้แสดงตำแหน่งของ Flutter Engine
|
||||
ในโครงสร้างนี้ เน้นขอบเขตของ API และระบุที่เก็บโค้ด (repository) ที่ส่วนประกอบแต่ละส่วนอยู่
|
||||
คำอธิบายด้านล่างจะอธิบายคำศัพท์บางคำที่ใช้กันทั่วไปในการอธิบายส่วนประกอบของแอป Flutter
|
||||
|
||||
#afigure(
|
||||
grid(
|
||||
columns: 2,
|
||||
align: horizon,
|
||||
image(
|
||||
"Flutter/mobileExampleApp.png",
|
||||
height: 2.5in,
|
||||
alt: "แอพลิเคชันมือถือ มีแถบสีม่วง ตัวเลขแสดงจำนวนครั้งที่กดปุ่มและปุ่มกดเพิ่มจำนวน",
|
||||
),
|
||||
image(
|
||||
"Flutter/desktopExampleApp.png",
|
||||
width: 90%,
|
||||
alt: "โปรแกรมคอมพิวเตอร์ แถบหน้าต่างโปรแกรมสีดำ ในหน้าต่างประกอบด้วยส่วนประกอบคล้ายแอพลิเคชันบนโทรศัพท์",
|
||||
),
|
||||
),
|
||||
caption: [แอพลิเคชันตัวอย่างบน Android 15 และ Arch Linux],
|
||||
)
|
||||
|
||||
#show raw.where(block: true): set block(below: 2em)
|
||||
|
||||
_*หมายเหตุ:* โคดในห้วข้อนี้ถูกนำ comment ออกเพื่อความรวบรัด_
|
||||
|
||||
ภายในโฟลเดอร์โปรเจกต์ใหม่ จะมีไฟล์ `lib/main.dart` พร้อมแอพลิเคชันตัวอย่าง
|
||||
|
||||
โดยในบรรทัดแรก จะมีการนำเข้า Material UI
|
||||
|
||||
#set figure(kind: "image", supplement: "รูปที่")
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
import 'package:flutter/material.dart';
|
||||
```,
|
||||
caption: [โคดนำเข้าแพคเกจ],
|
||||
)
|
||||
|
||||
และถัดมา จะมีฟังก์ชันหลักชื่อ `main` ที่ทำหน้าที่ในการรันแอพลิเคชัน โดยมีการรับอาร์กิวเมนต์เป็นวิดเจ็ท
|
||||
ซึ่งในกรณีนี้เป็นการสร้างวัตถุจากคลาส `MyApp` ที่เป็นวิดเจ็ท
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
void main() {
|
||||
runApp(const MyApp());
|
||||
}
|
||||
```,
|
||||
caption: [ฟังก์ชัน main],
|
||||
)
|
||||
|
||||
ถัดมาจะมีคลาส `MyApp` ที่สืบทอดมาจาก `StatelessWidget` ซึ่งคือคลาสสำหรับวิดเจ็ทที่ไร้สถานะ
|
||||
("Stateless")
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
class MyApp extends StatelessWidget {
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
ซึ่งในคลาสจะมี constructor ที่สามารถรับค่าคีย์ได้:
|
||||
#afigure(
|
||||
```dart
|
||||
const MyApp({super.key});
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
และจะมีฟังก์ชันในการสร้างวิดเจ็ท ซึ่งฟังก์ชันนี้เป็นการสืบทอดฟังก์ชันมา สังเกตได้จาก `@override`
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
และในฟังก์ชันจะมีการสร้างวัตถุ MaterialApp ซึ่งมีหน้าที่ในการเก็บข้อมูลเกี่ยวกับแอพลิเคชัน Material
|
||||
UI รวมถึงข้อมูลเช่น ชื่อแอพลิเคชัน (`title`) และธีม (`theme`)
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
return MaterialApp(
|
||||
title: 'Flutter Demo',
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
โดยข้อมูลธีมนั้นถูกเก็บด้วยการสร้างวัตถุ `ThemeData`
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
theme: ThemeData(
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
และมีการสร้างธีมสีจากสีหลักโดยการใช้เมธอด `ColorScheme.fromSeed` แต่ในโคดด้านล่างนี้ คลาส
|
||||
`ColorScheme` นั้นถูกอนุมานขึ้นมา โดยใน Dart 3.10 มีฟีเจอร์ "dot shorthands"
|
||||
ซึ่งเป็นทางลัดในการข้ามการเขียนชื่อคลาส ซึ่งชื่อคลาสสามารถถูกอนุมานขึ้นมาได้เนื่องจากอาร์กิวเมนต์
|
||||
`colorScheme` นั้นคาดหวังค่าที่เป็นวัตถุจากคลาส `ColorScheme` อยู่แล้ว
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
colorScheme: .fromSeed(seedColor: Colors.deepPurple),
|
||||
),
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
และต่อมา อาร์กิวเมนต์ `home` เป็นอาร์กิวเมนต์ที่รับค่าเป็นวิดเจ็ทซึ่งจะเป็นหน้าแรกของแอพลิเคชัน
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
home: const MyHomePage(title: 'Flutter Demo Home Page'),
|
||||
);
|
||||
}
|
||||
}
|
||||
```,
|
||||
kind: "image",
|
||||
supplement: "รูปที่",
|
||||
caption: [],
|
||||
)
|
||||
|
||||
ถัดมา มีการสร้างคลาส `MyHomePage` ที่ถูกใช้ด้านบน โดยคลาสเป็น `StatefulWidget`
|
||||
ซึ่งหมายความว่า เป็นคลาสที่มีสถานะ (State)
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
class MyHomePage extends StatefulWidget {
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
โดยใน constructor มีการรับค่าพารามีเตอร์ `title`
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
const MyHomePage({super.key, required this.title});
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
โดยคลาสนี้เป็นคลาสที่เก็บการตั้งค่าวิดเจ็ท และเป็นคลาสที่เก็บค่าพารามิเตอร์จากวิดเจ็ทที่เหนือกว่า
|
||||
และตัวแปรในคลาสย่อยของ `StatefulWidget` นั้นจะมีคีย์เวิร์ด `final` เสมอ ซึ่งหมายถึงว่า
|
||||
ตัวแปรนี้เปลี่ยนแปลงไม่ได้หลังจากสร้างวัตถุจากคลาสแล้ว
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
final String title;
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
ต่อมาจึงมีการสร้างวัตถุ State ซึ่งในฟังก์ชัน `createState` ที่ถูกสืบทอดมานั้น จะมีการสร้างวัตถุ State
|
||||
จากคลาส `_MyHomePageState` (โดยที่ `_`
|
||||
หมายถึงว่าคลาสนั้นเป็นส่วนตัวและไม่ควรถูกนำเข้าโดยไฟล์อื่น)
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
@override
|
||||
State<MyHomePage> createState() => _MyHomePageState();
|
||||
}
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
int _counter = 0;
|
||||
|
||||
void _incrementCounter() {
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
โดยในฟังก์ชัน `_incrementCounter` มีการเรียกใช้ฟังก์ชัน `setState` ซึ่งจะแจ้งเตือน Flutter
|
||||
ว่ามีการเปลี่ยนแปลงสถานะ ซึ่งจะก่อให้เกิดการเร็นเดอร์วิดเจ็ทใหม่ และในอาร์กิวเมนต์ของ `setState`
|
||||
คือฟังก์ชันไม่ระบุชื่อ (anonymous functions หรืออีกชื่อหนึ่งคือ lambda) ที่เปลี่ยนแปลงสถานะของวิดเจ็ท
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
setState(() {
|
||||
_counter++;
|
||||
});
|
||||
}
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
โดยต่อมา มีฟังก์ชัน `build` เช่นเคยที่มีหน้าที่ในการสร้างวิดเจ็ท โดยฟังก์ชัน `build`
|
||||
ของวิดเจ็ทที่มีสถานะนั้นจะถูกรันใหม่ทุกครั้งที่มีการเปลี่ยนแปลงสถานะ
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
*การทดลอง:* ในระหว่างที่รันแอพลิเคชันอยู่ ลองเปลี่ยนสีพื้นหลังของวิดเจ็ท `AppBar` (เป็นค่าอื่นเช่น
|
||||
`Colors.amber`) แล้วทำการ hot reload โดยการกดไอคอน#box(
|
||||
image("Flutter/flutterHotReload.svg", alt: "สายฟ้า", width: 1.5em),
|
||||
baseline: 20%,
|
||||
)เพื่อเห็นการเปลี่ยนแปลงของสีแถบแอพลิเคชันในระหว่างที่สีของวิดเจ็ทอื่น ๆ ยังคงเดิม
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
โดยในอาร์กิวเมนต์ `title` นี้มีการใช้ค่าที่รับมาจากวิดเจ็ทที่เหนือกว่า โดย `widget`
|
||||
ในที่นี้คือวัตถุของคลาส `MyHomePage` ที่ทำหน้าที่เก็บค่า `title` ของเรา แล้วเราจึงทำค่า `title`
|
||||
นั้นใส่ในวิดเจ็ทข้อความ (`Text`)
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
title: Text(widget.title),
|
||||
),
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
`Center` เป็นวิดเจ็ทจัดเลย์เอาต์ โดยจะทำให้ลูก 1 วิดเจ็ทของมัน (`child`) อยู่ตรงกลาง
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
body: Center(
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
และ `Column` เป็นวิดเจ็ทจัดเลย์เอาต์เช่นกัน มันรับลูกหลายคน (`children`) แล้วจัดเรียงมันในแนวตั้ง
|
||||
โดยค่าเริ่มต้นแล้ว มันจะจัดให้ตัวเองกว้างเท่ากับลูก ๆ ของมัน
|
||||
และพยายามจัดให้ตัวเองสูงเท่าวิดเจ็ทที่สูงกว่า
|
||||
|
||||
วิดเจ็ทคอลัมน์มีหลายคุณสมบัติในการควบคุมขนาดของมันและการจัดวางลูก ๆ ของมัน
|
||||
โดยด้านล่างมีการใช้อาร์กิวเมนต์ `mainAxisAlignment` ในการจัดลูก ๆ ของมันให้อยู่ตรงกลางในแนวตั้ง
|
||||
โดย "main axis" หรือ แกนหลัก ในกรณีนี้คือแนวตั้ง เพราะคอลัมน์นั้นเป็นแนวตั้ง (และ "cross axis"
|
||||
หรือแกนไขว้ จะเป็นแนวนอน คือแนวตรงข้ามกับแนวหลัก)
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
child: Column(
|
||||
mainAxisAlignment: .center,
|
||||
children: [
|
||||
const Text('You have pushed the button this many times:'),
|
||||
Text(
|
||||
'$_counter',
|
||||
```,
|
||||
caption: [],
|
||||
)
|
||||
|
||||
การเข้าถึงธีมของแอพลิเคชัน (```dart Theme.of(context)```) แล้วนำธีมข้อความ
|
||||
`headlineMedium` มาใช้:
|
||||
|
||||
#afigure(
|
||||
```dart
|
||||
style: Theme.of(context).textTheme.headlineMedium,
|
||||
), // Text
|
||||
],
|
||||
), // Column
|
||||
), // Center
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _incrementCounter,
|
||||
tooltip: 'Increment',
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
```,
|
||||
caption: [],
|
||||
image("Flutter/app-anatomy.svg", width: 3in),
|
||||
attr: [Flutter, ภายใต้ CC BY 4.0],
|
||||
alt: "แผนผังสถาปัตยกรรม Flutter",
|
||||
caption: [สถาปัตยกรรม Flutter],
|
||||
)
|
||||
|
||||
- แอปพลิเคชัน Dart (Dart app)
|
||||
- ประกอบวิดเจ็ตเข้าด้วยกันเพื่อสร้าง UI ที่ต้องการ
|
||||
- ดำเนินการตามตรรกะทางธุรกิจ
|
||||
- นักพัฒนาแอปเป็นเจ้าของ
|
||||
- เฟรมเวิร์ก (Framework)
|
||||
- ให้ API ระดับสูงสำหรับการสร้างแอปคุณภาพสูง (ตัวอย่างเช่น วิดเจ็ต การทดสอบการกด
|
||||
การตรวจจับท่าทาง การเข้าถึงได้ และการอินพุตข้อความ)
|
||||
- ประกอบต้นวิดเจ็ตของแอปพลิเคชันเป็นฉาก
|
||||
#pagebreak()
|
||||
|
||||
== โครงสร้างโปรเจกต์ Flutter <flStructure>
|
||||
|
||||
ในโครงงานนี้ โปรเจกต์ Flutter มีโครงสร้างคร่าว ๆ ดังกล่าว
|
||||
|
||||
#tree-list[
|
||||
- android
|
||||
- app
|
||||
- src
|
||||
- main
|
||||
- java: โคด Java
|
||||
- kotlin: โคด Kotlin
|
||||
- res: โฟลเดอร์ทรัพยากร เช่น ไอคอนแอพลิเคชัน
|
||||
- AndroidManifest.xml
|
||||
- build.gradle.kts
|
||||
- settings.gradle.kts
|
||||
- assets
|
||||
- certificates
|
||||
- rootCA.crt: ใบรับรอง Root (ดู@x509 สำหรับรายละเอียด)
|
||||
- build: โฟลเดอร์สำหรับเก็บไฟล์ไบนารี
|
||||
- ios
|
||||
- lib: ซอร์สโคดของแอพลิเคชัน
|
||||
- linux
|
||||
- macos
|
||||
- test
|
||||
- windows
|
||||
- l10n.yaml: ไฟล์ตั้งค่าฟีเจอร์แปลภาษา
|
||||
- pubspec.yaml: ไฟล์ข้อมูลโปรเจกต์ Flutter
|
||||
]
|
||||
|
||||
(รายการข้างต้นรวมถึงแค่ไฟล์ที่สำคัญที่จะถูกกล่าวถึงใน@flutter นี้)
|
||||
|
||||
== การนำเข้าแพคเกจ
|
||||
|
||||
#i ไฟล์ `pubspec.yaml` เป็นไฟล์ที่เก็บข้อมูลเกี่ยวกับโปรเจกต์ Flutter ของคุณ เช่น ชื่อ คำอธิบาย
|
||||
เวอร์ชัน และรวมถึงสิ่งที่จะกล่าวถึงในหัวข้อนี้ คือการติดตั้งและนำเข้าแพคเกจภายนอกมาใช้ในโปรเจกต์
|
||||
|
||||
#i โดยหากไม่รวมรายละเอียดโปรเจกต์เบื้องต้นเช่นชื่อและคำอธิบายแล้ว ไฟล์ `pubspec.yaml`
|
||||
จะมีรายละเอียดดังนี้
|
||||
|
||||
`environment` นั้นจะกล่าวถึงสิ่งแวดล้อม ซึ่งในกรณีนี้มีเพียง `sdk` ที่ระบุเวอร์ชันของ Flutter SDK
|
||||
ในการคอมไพล์โปรเจกต์
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
sdk: ^3.10.1
|
||||
```
|
||||
|
||||
`dependencies` จะกล่าวถึงไลบรารีที่โปรเจกต์พึ่งพา ซึ่งโดยค่าเริ่มต้นแล้ว
|
||||
ในโปรเจกต์ตัวอย่างจะมีการติดตั้งเซ็ทไอคอน Cupertino มาให้ (`cupertino_icons`;
|
||||
หรือเรียกอย่างง่ายว่า ไอคอน iOS) ซึ่งแน่นอนว่าหากคุณไม่ใช้ สามารถลบทิ้งได้
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
cupertino_icons: ^1.0.8
|
||||
```
|
||||
|
||||
`dev_dependencies` กล่าวถึงไลบรารีที่โปรเจกต์พึ่งพา#emph([ในการพัฒนา]) หมายความว่า
|
||||
ไลบรารีเหล่านี้จะไม่ถูกใส่เข้าไปยังแอพลิเคชันของคุณโดยตรง โดยตามค่าเริ่มต้นแล้ว จะมีแพคเกจ
|
||||
`flutter_test` ที่ถูกดึงมาจาก Flutter SDK โดยตรง และมี `flutter_lints`
|
||||
สำหรับการตรวจข้อผิดพลาดในโคด
|
||||
|
||||
```yaml
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
flutter_lints: ^6.0.0
|
||||
```
|
||||
|
||||
`flutter` เป็นการตั้งค่าเกี่ยวกับ Flutter โดยที่ตามค่าเริ่มต้นแล้วจะมีค่า `uses-material-design`
|
||||
มาให้เป็น `true` ซึ่งจะเป็นการบอกกับ Flutter ว่าแอพลิเคชันนั้นใช้ Material design
|
||||
|
||||
```yaml
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
```
|
||||
|
||||
และนอกจากนั้นแล้ว ในส่วนของ `flutter`
|
||||
นี้จะเป็นส่วนที่ลิสต์รายการไฟล์เพิ่มเติมที่ต้องการใส่เข้าไปในแอพลิเคชันด้วยเช่นกัน ตัวอย่างเช่น
|
||||
โครงงานนี้มีการเพิ่มเติมในส่วน `flutter` ดังนี้:
|
||||
|
||||
```yaml
|
||||
assets:
|
||||
- assets/certificates/rootCA.crt
|
||||
```
|
||||
|
||||
โดยจะเป็นการเพิ่มไฟล์ใบรับรอง `rootCA.crt` เข้าไปกับแอพลิเคชันเพื่อใช้ในการส่งคำขอ HTTPS
|
||||
ไปยังอุปกรณ์ของโครงงาน
|
||||
|
||||
#pagebreak()
|
||||
- เอนจิน (Engine)
|
||||
- มีหน้าที่แปลงฉากเป็นรูปแบบแรสเตอร์
|
||||
- ให้การทำงานระดับต่ำของแกนกลางของ Flutter API (เช่น กราฟิก การจัดข้อความ และรันไทม์
|
||||
Dart)
|
||||
- เปิดเผยฟังก์ชันระดับนี้ให้แก่เฟรมเวิร์กผ่าน API `dart:ui`
|
||||
- บูรณาการกับแพลตฟอร์มต่าง ๆ ด้วย API ตัวฝังตัว
|
||||
- ตัวฝังตัว (Embedder)
|
||||
- ประสานงานกับระบบปฏิบัติการภายใต้สำหรับการเข้าถึงบริการต่าง ๆ เช่น พื้นผิวการเรนเดอร์
|
||||
การเข้าถึง และการป้อนข้อมูล
|
||||
- จัดการลูปอิเวนต์
|
||||
- เปิดเผย API เฉพาะแพลตฟอร์มเพื่อบูรณาการตัวฝังตัวเข้าไปยังแอป
|
||||
- ตัวรัน (Runner)
|
||||
- ประกอบชิ้นส่วนที่ถูกเปิดเผยโดยตัวฝังตัวเข้าเป็นแพคเกจแอปพลิเคชันที่สามารถใช้งานได้บนแพลตฟอร์มเป้าหมาย
|
||||
- บางส่วนถูกสร้างขึ้นโดย `flutter create` และมีเจ้าของเป็นผู้พัฒนาแอป
|
||||
|
||||
== ระบบการดีไซน์
|
||||
|
||||
โดยใน Flutter แล้วนั้น ไม่รวมแพคเกจบุคคลที่สาม จะมีระบบการดีไซน์อยู่สองแบบคือ:
|
||||
#iii โดยใน Flutter แล้วนั้น ไม่รวมแพคเกจบุคคลที่สาม จะมีระบบการดีไซน์อยู่สองแบบคือ:
|
||||
|
||||
+ Material Design: การดีไซน์ของ Google สำหรับ Android
|
||||
+ Cupertino Design: การดีไซน์ของ Apple สำหรับ iOS
|
||||
#[
|
||||
#set enum(indent: 5.5em)
|
||||
+ Material Design: การดีไซน์ของ Google สำหรับ Android
|
||||
+ Cupertino Design: การดีไซน์ของ Apple สำหรับ iOS
|
||||
]
|
||||
|
||||
*หมายเหตุ:* Cupertino Design ถูกแทนที่โดย Liquid Glass แล้ว โดยในปัจจุบันทีม Flutter
|
||||
กำลังทำการตรวจสอบและแก้ไขโครงสร้างระบบดีไซน์ ดังนั้น หากมีผู้พัฒนาต้องการใช้เอฟเฟกต์ Liquid
|
||||
Glass ในแอพลิเคชัน Flutter จึงจำเป็นต้องพึงพาแพคเกจบุคคลที่สามก่อนในขณะนี้ (Flutter เวอร์ชัน
|
||||
3.38.3 ณ เวลาที่พิมพ์)
|
||||
#iii *หมายเหตุ:* Cupertino Design ถูกแทนที่โดย Liquid Glass แล้ว โดยในปัจจุบันทีม Flutter
|
||||
กำลังทำการตรวจสอบและแก้ไขโครงสร้างระบบดีไซน์ ดังนั้น หากมีผู้พัฒนาต้องการใช้เอฟเฟกต์#jb Liquid
|
||||
Glass ในแอปพลิเคชัน Flutter จึงจำเป็นต้องพึงพาแพคเกจบุคคลที่สามก่อนในขณะนี้ (Flutter เวอร์ชัน
|
||||
3.38.5 ณ เวลาที่พิมพ์)
|
||||
|
||||
#i แอพลิเคชันในโครงงานนี้ใช้ Material Design เนื่องจากมีเป้าหมายหลักเป็นแพลตฟอร์ม Android
|
||||
โดย Material Design คือภาษาการดีไซน์ที่ถูกพัฒนาโดย Google และถูกเปิดตัวครั้งแรก 25 มิถุนายน
|
||||
#iii Material Design คือภาษาการดีไซน์ที่ถูกพัฒนาโดย Google และถูกเปิดตัวครั้งแรก 25 มิถุนายน
|
||||
2014 และมีเวอร์ชันหลัก 3 เวอร์ชันด้วยกัน โดยที่เวอร์ชันที่ 3 ถูกเปิดตัวในงาน Google I/O 2021
|
||||
และมีชื่อว่า "Material You" (แต่ชื่อธรรมดา "Material Design 3" ก็ยังถูกใช้งานกันอย่างปกติ)
|
||||
และในงาน Google I/O 2025 มีการเปิดตัว "Material 3 Expressive" ซึ่งเป็นการปรับปรุงต่อจาก
|
||||
Material You เดิมสำหรับ Android 16 และ Wear OS 6 และสามารถดูรายละเอียดเพิ่มเติมเกี่ยวกับ
|
||||
Material 3 ได้ที่ https://m3.material.io/
|
||||
และมีชื่อว่า "Material You" (แต่ชื่อธรรมดา "Material Design 3" ก็ยังถูกใช้งานกันอย่างปกติ)#jb
|
||||
และในงาน Google I/O 2025 มีการเปิดตัว "Material 3 Expressive"
|
||||
ซึ่งเป็นการปรับปรุงต่อจาก#jb Material You เดิมสำหรับ Android 16 และ Wear OS 6
|
||||
และสามารถดูรายละเอียดเพิ่มเติมเกี่ยวกับ Material 3 ได้ที่ https://m3.material.io/
|
||||
|
||||
== ข้อมูลเกี่ยวกับแพลตฟอร์ม
|
||||
== ส่วนติดต่อผู้ใช้ที่มีปฏิกิริยา
|
||||
|
||||
=== Android <flAndroid>
|
||||
#iii บนพื้นผิว Flutter เป็นเฟรมเวิร์ก UI แบบ reactive และ declarative
|
||||
ซึ่งนักพัฒนาเป็นผู้จัดเตรียมการแมปจากสถานะแอปพลิเคชันไปยังสถานะอินเทอร์เฟซ
|
||||
และเฟรมเวิร์กจะทำหน้าที่อัปเดตอินเทอร์เฟซขณะรันไทม์เมื่อสถานะของแอปพลิเคชันเปลี่ยนแปลง
|
||||
โมเดลนี้ได้รับแรงบันดาลใจจากงานที่มาจาก Facebook สำหรับเฟรมเวิร์ก React ของพวกเขา
|
||||
ซึ่งรวมถึงการทบทวนหลักการออกแบบแบบดั้งเดิมหลายประการ
|
||||
|
||||
#i ในการพัฒนาแอพลิเคชัน Android โดยใช้เฟรมเวิร์ก Flutter
|
||||
จำเป็นต้องใช้ส่วนประกอบเครื่องมือพัฒนา Android ดังนี้
|
||||
#iii ในเฟรมเวิร์ก UI แบบดั้งเดิมส่วนใหญ่ สถานะเริ่มต้นของอินเทอร์เฟซผู้ใช้จะถูกอธิบายเพียงครั้งเดียว
|
||||
จากนั้นจึงอัปเดตแยกกันด้วยโคดผู้ใช้ ณ รันไทม์ เพื่อตอบสนองต่อเหตุการณ์
|
||||
ความท้าทายประการหนึ่งของแนวทางนี้คือ เมื่อแอปพลิเคชันมีความซับซ้อนมากขึ้น
|
||||
นักพัฒนาจำเป็นต้องทราบว่าสถานะเปลี่ยนแปลงไปอย่างไรตลอดทั้ง UI ตัวอย่างเช่น พิจารณา UI ต่อไปนี้:
|
||||
|
||||
- Android SDK (API Level 36 ณ เวลาที่พิมพ์)
|
||||
- Android SDK Build-Tools
|
||||
- Android SDK Command-line Tools
|
||||
- Android SDK Platform-Tools
|
||||
- Android Emulator (ไม่บังคับ)
|
||||
|
||||
และแนะนำให้จัดการและติดตั้งเครื่องมือเหล่านี้ผ่าน Android Studio
|
||||
|
||||
#i ในการติดตั้ง Android SDK ควรติดตั้ง Android SDK
|
||||
ล่าสุดถึงแม้ว่าอุปกรณ์ของคุณจะใช้เวอร์ชันที่เก่ากว่านั้น
|
||||
เพื่อความมั่นใจว่าแอพลิเคชันจะสามารถใช้กับอุปกรณ์ที่ใหม่ล่าสุดได้
|
||||
|
||||
#i แอพลิเคชัน Android จะมี SDK/API level เป้าหมาย (Target SDK/API level) และ SDK/API
|
||||
level ขั้นต่ำ (Minimum SDK/API level) โครงงานนี้ ณ เวลาที่พิมพ์ ใช้ API level เป้าหมาย 36
|
||||
(Android 16) และ API level ขั้นต่ำ 24 (Android 7) ซึ่งรวมกันแล้ว แอพลิเคชัน Android
|
||||
จะสามารถติดตั้งได้บนระบบตั้งแต่ API level ขั้นต่ำจนถึง API level เป้าหมาย หรือก็คือ
|
||||
แอพลิเคชันในโครงงานนี้สามารถติดตั้งได้ตั้งแต่บนระบบ Android 7 ถึง Android 16 นั่นเอง
|
||||
|
||||
==== Java/Kotlin
|
||||
|
||||
#i Java และ Kotlin เป็นภาษาสำคัญสำหรับการพัฒนาแอพลิเคชัน Android ถึงอย่างไรก็ตาม แอพลิเคชัน
|
||||
Flutter นั้นถูกเขียนด้วยภาษา Dart แต่ยังจำเป็นต้องมีโคด Java และ Kotlin
|
||||
เล็กน้อยเพื่อเริ่มต้นแอพลิเคชัน Flutter
|
||||
|
||||
#i โดยปกติแล้ว Flutter จะสร้างโคดพื้นฐานขึ้นมาให้สำหรับการเริ่มแอพลิเคชันแบบพื้นฐาน
|
||||
(อยู่ภายในโฟลเดอร์ `java` และ `kotlin` ตามที่ถูกกล่าวถึงใน@flStructure)
|
||||
ดังนั้นจึงไม่จำเป็นต้องมีการเขียนโคด Java หรือ Kotlin เอง แต่ในบางกรณี
|
||||
อาจต้องเขียนโคดเพิ่มเองหากมีความต้องการเข้าถึงฟีเจอร์พื้นฐานระบบที่ Flutter ไม่มี API
|
||||
เพื่อให้เข้าถึงได้และไม่มีแพคเกจเพื่อรองรับฟีเจอร์ที่ต้องการ
|
||||
|
||||
#i โครงการนี้ใช้ Java 21 (JetBrains Runtime/Azul Zulu OpenJDK) เป็นหลักในการทำงานกับ
|
||||
Gradle แต่แอพลิเคชัน Android ที่ผลิตออกมานั้น เพื่อให้เข้ากับเวอร์ชันที่เก่ากว่าของระบบปฏิบัติการได้ ใช้
|
||||
Java 11
|
||||
|
||||
==== Gradle
|
||||
|
||||
#i Gradle เป็นเครื่องมือสร้างระบบอัตโนมัติสำหรับการพัฒนาซอฟต์แวร์หลายภาษา จัดการงานต่าง ๆ เช่น
|
||||
การคอมไพล์ การแพ็คเกจ การทดสอบ การปรับใช้ และการเผยแพร่ ภาษาที่รองรับ ได้แก่ Java
|
||||
(รวมถึงภาษา Kotlin, Groovy, Scala ที่ใช้ JDK), C/C++ และ JavaScript Gradle
|
||||
พัฒนาต่อยอดจากแนวคิดของ Apache Ant และ Apache Maven และนำเสนอภาษาเฉพาะโดเมนที่ใช้
|
||||
Groovy และ Kotlin ซึ่งต่างจากการกำหนดค่าโครงการที่ใช้ XML ที่ Maven ใช้ Gradle
|
||||
ใช้กราฟแบบอะไซคลิกกำกับทิศทางเพื่อจัดการการอ้างอิง กราฟนี้ใช้เพื่อกำหนดลำดับของงานที่ควรดำเนินการ
|
||||
Gradle ทำงานบน Java Virtual Machine
|
||||
|
||||
#i Gradle คือเครื่องมือหลักที่ใช้ในการจัดการโปรเจกต์ Java ส่วนใหญ่ รวมถึงโปรเจกต์ Android
|
||||
โดยในโครงการนี้ จะใช้ Gradle เวอร์ชัน 8.14.3 เป็นหลัก
|
||||
|
||||
#i โดยปกติแล้ว ผู้พัฒนานั้นไม่มีความจำเป็นที่จะต้องแตะต้อง Gradle ด้วยตนเอง และ Flutter
|
||||
จะทำการจัดการเอง แต่หากมีความจำเป็นต้องใช้คำสั่ง Gradle ด้วยตนเอง จะมีสคริปต์ `gradlew` (หรือ
|
||||
`gradlew.bat` สำหรับผู้ใช้ Windows) ภายในโฟลเดอร์ `android` ของโปรเจกต์ Flutter
|
||||
เสมอเพื่อเรียกใช้ Gradle ที่ถูกดาวน์โหลดมาสำหรับโปรเจกต์นั้น ๆ
|
||||
|
||||
=== Linux <flLinuxDetails>
|
||||
|
||||
#i เช่นเดียวกับ Android ที่กล่าวไปข้างต้น Flutter มีการสร้างโคดสำหรับการเปิดแอพลิเคชันแบบพื้นฐาน
|
||||
แต่สำหรับ Linux แล้วนั้น Flutter ใช้โคด C++ และเฟรมเวิร์ก CMake
|
||||
ในการสร้างรากฐานของแอพลิเคชัน
|
||||
|
||||
#i ในการพัฒนาแอพลิเคชันสำหรับ Linux ต้องติดตั้งโปรแกรมเพิ่มเติม (build dependencies)
|
||||
ขยายความคือ ด้านบนคือสิ่งที่จำเป็นหากมีระบบอื่นเป็นเป้าหมาย แต่หากต้องการพัฒนาแอพลิเคชัน Linux
|
||||
ต้องติดตั้งโปรแกรมในรายการด้านล่างเพิ่ม
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
column-gutter: 1in,
|
||||
[
|
||||
- GTK 3 (ไลบรารีสำหรับการพัฒนา)
|
||||
- pkg-config
|
||||
- ไลบรารี GNU Standard C++ v3
|
||||
],
|
||||
[
|
||||
- Clang
|
||||
- CMake
|
||||
- Ninja
|
||||
],
|
||||
#afigure(
|
||||
image("Flutter/color-picker.png", width: 70%),
|
||||
alt: "หน้าต่างเลือกสี",
|
||||
caption: [หน้าต่างเลือกสี],
|
||||
)
|
||||
|
||||
#i การติดตั้งไลบรารีและโปรแกรมที่กล่าวไปข้างต้นจะแตกต่างกันไปแต่ละการแจกจ่าย Linux และ
|
||||
Flutter ใช้ไลบรารีพื้นฐานดังกล่าวในการทำงานของแอพลิเคชัน (runtime dependencies)
|
||||
#iii มีหลายที่ที่สามารถเปลี่ยนสถานะได้: กล่องสี, แถบเลื่อนเฉดสี, ปุ่มตัวเลือก เมื่อผู้ใช้โต้ตอบกับ UI
|
||||
การเปลี่ยนแปลงจะต้องสะท้อนให้เห็นในทุกที่ ที่เลวร้ายยิ่งกว่านั้น เว้นแต่จะได้รับการดูแล
|
||||
การเปลี่ยนแปลงเล็กน้อยในส่วนใดส่วนหนึ่งของอินเทอร์เฟซผู้ใช้อาจทำให้เกิดเอฟเฟกต์คลื่นส่งผลกระทบกับโค้ดที่ดูเหมือนจะไม่เกี่ยวข้องกัน
|
||||
|
||||
- GTK 3
|
||||
- blkid
|
||||
- LZMA
|
||||
#iii วิธีแก้ปัญหาอย่างหนึ่งคือแนวทางเช่น MVC
|
||||
โดยที่คุณส่งข้อมูลการเปลี่ยนแปลงไปยังโมเดลผ่านคอนโทรลเลอร์
|
||||
จากนั้นโมเดลจะพุชสถานะใหม่ไปยังมุมมองผ่านคอนโทรลเลอร์ อย่างไรก็ตาม#jb สิ่งนี้ก็เป็นปัญหาเช่นกัน
|
||||
เนื่องจากการสร้างและการอัปเดตองค์ประกอบ UI
|
||||
เป็นขั้นตอนสองขั้นตอนที่แยกจากกันซึ่งอาจไม่ซิงค์กันได้อย่างง่ายดาย
|
||||
|
||||
แต่โดยทั่วไปแล้ว ไลบรารีเหล่านี้ควรถูกติดตั้งมาอยู่แล้วหากคุณใช้ graphical desktop ทั่วไป
|
||||
#iii Flutter พร้อมด้วยเฟรมเวิร์กเชิงโต้ตอบอื่น ๆ ใช้แนวทางอื่นในการแก้ไขปัญหานี้
|
||||
โดยแยกอินเทอร์เฟซผู้ใช้ออกจากสถานะพื้นฐานอย่างชัดเจน ด้วย API สไตล์ React
|
||||
คุณจะสร้างเฉพาะคำอธิบาย UI เท่านั้น
|
||||
และเฟรมเวิร์กจะดูแลการใช้การกำหนดค่านั้นเพื่อสร้างหรืออัปเดตอินเทอร์เฟซผู้ใช้ตามความเหมาะสม
|
||||
|
||||
==== Debian
|
||||
#iii ใน Flutter วิดเจ็ต (คล้ายกับส่วนประกอบใน React)
|
||||
จะแสดงด้วยคลาสที่ไม่เปลี่ยนรูปซึ่งใช้ในการกำหนดค่าแผนผังของวัตถุ
|
||||
วิดเจ็ตเหล่านี้ถูกใช้เพื่อจัดการแผนผังวัตถุที่แยกจากกันสำหรับโครงร่าง
|
||||
ซึ่งจากนั้นจะใช้ในการจัดการแผนผังวัตถุที่แยกจากกันสำหรับการประกอบ หัวใจหลักของ Flutter
|
||||
คือชุดของกลไกในการอัพเดทส่วนที่ดัดแปลงของแผนผังวิดเจ็ตอย่างมีประสิทธิภาพ
|
||||
การแปลงแผนผังหลายแผนผังของวัตถุให้เป็นแผนผังระดับล่างของวัตถุ
|
||||
และการแพร่กระจายการเปลี่ยนแปลงไปยังแผนผังวิดเจ็ตเหล่านี้
|
||||
|
||||
```sh
|
||||
# Development dependencies:
|
||||
sudo apt install curl git unzip xz-utils zip libglu1-mesa
|
||||
#iii วิดเจ็ตประกาศส่วนติดต่อผู้ใช้โดยการเขียนทับเมธอด `build()` ซึ่งเป็นฟังก์ชันที่แปลงสถานะเป็น
|
||||
UI:
|
||||
|
||||
# Linux build dependencies:
|
||||
sudo apt install clang cmake ninja-build pkg-config libgtk-3-dev libstdc++-12-dev
|
||||
#afigure(
|
||||
```
|
||||
UI = f(state)
|
||||
```,
|
||||
kind: image,
|
||||
caption: [สูตรแสดงการทำงานอย่างคร่าว],
|
||||
)
|
||||
|
||||
# Runtime dependencies:
|
||||
sudo apt install libgtk-3-0 libblkid1 liblzma5
|
||||
```
|
||||
#iii เมธอด `build()` นั้นตามการออกแบบแล้วเป็นเมธอดที่เร็วและควรที่จะไม่มีผลข้างเคียง
|
||||
ทำให้เมธอดนั้นสามารถถูกเรียกใช้โดยเฟรมเวิร์กเมื่อไหร่ก็ได้ที่จำเป็น
|
||||
(เป็นไปได้ที่จะบ่อยมากและมีการเรียกใช้หนึ่งครั้งต่อหนึ่งเฟรม)
|
||||
|
||||
==== Fedora Linux
|
||||
#iii วิธีนี้พึ่งพาลักษณะเฉพาะรันไทม์ภาษา (หากเจาะจงคือการสร้างและทำลายวัตถุอย่างรวดเร็ว) ซึ่ง
|
||||
Dart นั้นเหมาะสำหรับงานนี้เป็นพิเศษ
|
||||
|
||||
```sh
|
||||
# Development dependencies:
|
||||
sudo dnf install curl git unzip xz zip mesa-libglu
|
||||
== ประวัติ
|
||||
|
||||
# Linux build dependencies:
|
||||
sudo dnf install clang cmake ninja-build pkgconf gtk3
|
||||
#iii Flutter เวอร์ชันแรกรู้จักกันในชื่อ "Sky" และทำงานบนระบบปฏิบัติการ Android
|
||||
มีการเปิดเผยในการประชุมสุดยอดนักพัฒนา Dart ประจำปี 2015
|
||||
โดยมีจุดประสงค์ที่ระบุไว้คือสามารถแสดงผลได้อย่างสม่ำเสมอที่ 120 เฟรมต่อวินาที เมื่อวันที่ 4 ธันวาคม
|
||||
2018 Flutter 1.0 เปิดตัวในการประชุม Flutter ที่ลอนดอน
|
||||
|
||||
# Runtime dependencies:
|
||||
sudo dnf install gtk3 libblkid xz
|
||||
```
|
||||
#iii ในวันที่ 6 พฤษภาคม 2020 ชุดพัฒนาซอฟต์แวร์ (SDK) Dart เวอร์ชัน 2.8 และ Flutter 1.17.0
|
||||
ได้รับการเผยแพร่ โดยเพิ่มการรองรับ Metal API
|
||||
|
||||
==== Arch Linux
|
||||
#iii เมื่อวันที่ 3 มีนาคม 2021 Google ได้เปิดตัว Flutter 2 ระหว่างกิจกรรม Flutter Engage
|
||||
ออนไลน์ ได้เพิ่มตัวเรนเดอร์ที่ใช้ Canvas สำหรับเว็บ นอกเหนือจากตัวเรนเดอร์ที่ใช้ HTML
|
||||
และการสนับสนุนแอปพลิเคชันเดสก์ท็อปแบบทดลองสำหรับ Windows, macOS, และ Linux
|
||||
นอกจากนี้ยังมาพร้อมกับ Dart 2.0 ซึ่งรวมถึงการสนับสนุนด้านความปลอดภัยแบบ null (null-safety)
|
||||
ความปลอดภัยแบบ null เป็นทางเลือกในตอนแรกเนื่องจากเป็นการเปลี่ยนแปลงครั้งใหญ่และบังคับใช้ใน
|
||||
Dart 3 ที่เปิดตัวในปี 2023
|
||||
|
||||
```sh
|
||||
# Development dependencies:
|
||||
sudo pacman -S --needed curl git unzip xz zip glu
|
||||
#iii ในวันที่ 12 พฤษภาคม 2022 Flutter 3 และ Dart 2.17
|
||||
ได้รับการเผยแพร่โดยมีการรองรับแพลตฟอร์มเดสก์ท็อปทั้งหมดอย่างเสถียร
|
||||
|
||||
# Linux build dependencies:
|
||||
sudo pacman -S --needed clang cmake ninja pkgconf gtk3
|
||||
#iii เมื่อวันที่ 27 ตุลาคม 2024 นักพัฒนาชุมชน Flutter จำนวนหนึ่งได้ประกาศเปิดตัว Flock
|
||||
ซึ่งเป็นเวอร์ชันแยกของ Flutter ที่มีจุดประสงค์เพื่อให้ง่ายต่อการร่วมพัฒนา
|
||||
ในขณะเดียวกันก็ยังคงรักษาความสอดคล้องกับทุกการเปลี่ยนแปลงที่เกิดขึ้นในโค้ดต้นทาง
|
||||
|
||||
# Runtime dependencies:
|
||||
sudo pacman -S --needed util-linux-libs xz gtk3
|
||||
```
|
||||
|
||||
=== macOS/iOS
|
||||
|
||||
#i การพัฒนาแอพลิเคชันสำหรับ macOS และ iOS นั้นต้องทำบน macOS
|
||||
เท่านั้นและจำเป็นต้องพึ่งพาเครื่องมือ Xcode แต่เนื่องจากในโครงงานนี้ไม่มีผู้ใช้ macOS
|
||||
จึงไม่สามารถสร้างไบนารีสำหรับ macOS และ iOS ออกมาได้ และไม่ใช่เป้าหมายของโครงงานนี้เช่นกัน
|
||||
#iii ในปี 2025 Google ยังคงพัฒนา Flutter ต่อไปด้วยสถาปัตยกรรมแบบโมดูลาร์ที่ได้รับการปรับปรุง
|
||||
การรองรับอุปกรณ์พับได้ และการเพิ่มประสิทธิภาพ ARM IoT ตามที่ระบุไว้ในแผนงานฉบับปรับปรุง
|
||||
|
||||
Reference in New Issue
Block a user