#import "../PageTemplate.typ": * #import "@preview/treet:1.0.0": * #import "@preview/tiaoma:0.3.0" #set heading(numbering: "1.1", offset: 1) #set figure(kind: image) = Flutter #i Flutter เป็นชุดพัฒนาซอฟต์แวร์ UI แบบโอเพนซอร์สที่สร้างโดย Google สามารถใช้พัฒนาแอปพลิเคชันข้ามแพลตฟอร์มจากฐานโคดเดียวสำหรับเว็บ Fuchsia, Android, iOS, Linux, macOS และ Windows โดย Flutter ได้รับการพูดถึงครั้งแรกในปี 2015 และเปิดตัวในเดือนพฤษภาคม 2017 และ Flutter ถูกใช้งานภายในโดย Google ในแอปพลิเคชันต่างๆ เช่น Google Pay และ Google Earth รวมถึงโดยนักพัฒนาซอฟต์แวร์รายอื่นๆ เช่น ByteDance และ Alibaba #i Flutter จะสร้างแอปพลิเคชันที่มีเอ็นจิ้นการเรนเดอร์ของตัวเอง ซึ่งส่งข้อมูลพิกเซลไปยังหน้าจอโดยตรง ซึ่งแตกต่างจากเฟรมเวิร์ก UI อื่น ๆ อีกมากมายที่อาศัยแพลตฟอร์มเป้าหมายเพื่อจัดหาเอ็นจิ้นการเรนเดอร์ เช่น แอป Android พื้นฐานที่ใช้ Android SDK ระดับอุปกรณ์ หรือ iOS SDK ที่ใช้ UI stack ในตัวของแพลตฟอร์มเป้าหมาย การควบคุมขั้นตอนการแสดงผลของ Flutter ช่วยลดความยุ่งยากในการรองรับหลายแพลตฟอร์ม เนื่องจากสามารถใช้โคด UI ที่เหมือนกันได้กับทุกแพลตฟอร์มเป้าหมาย == Dart #iii Dart เป็นภาษาโปรแกรมที่ออกแบบโดย Lars Bak และ Kasper Lund และพัฒนาโดย Google สามารถใช้พัฒนาแอปพลิเคชันบนเว็บ มือถือ เซิร์ฟเวอร์ และเดสก์ท็อปได้ และยังเป็นภาษาหลักที่ใช้ในการพัฒนาแอปพลิเคชัน Flutter #iii Dart เป็นภาษาเชิงวัตถุ อิงคลาส และรวบรวมขยะ (garbage-collection) ด้วยไวยากรณ์แบบ C สามารถคอมไพล์เป็นโค้ดเครื่อง JavaScript หรือ WebAssembly ได้ รองรับอินเทอร์เฟซ มิกซ์อิน คลาสนามธรรม เจเนอริกแบบรีไฟด์ และการอนุมานชนิดข้อมูล #pagebreak() == สถาปัตยกรรม #iii Flutter ถูกออกแบบมาให้เป็นระบบแบบเลเยอร์ที่ต่อขยายได้ ประกอบด้วยไลบรารีอิสระหลายชุดที่แต่ละชุดพึ่งพาเลเยอร์ที่อยู่ด้านล่าง ไม่มีเลเยอร์ใดที่มีสิทธิ์พิเศษในการเข้าถึงเลเยอร์ด้านล่าง และทุกส่วนของเฟรมเวิร์กถูกออกแบบมาให้เป็นตัวเลือกและสามารถทดแทนได้ #afigure( image("Flutter/archdiagram.png", width: 80%), attr: [Flutter, ภายใต้ CC BY 4.0], alt: "แผนผังสถาปัตยกรรม Flutter", caption: [สถาปัตยกรรม Flutter], ) #iii สำหรับระบบปฏิบัติการที่อยู่ภายใต้ แอปพลิเคชัน Flutter จะถูกบรรจุในลักษณะเดียวกับแอปพลิเคชันเนทีฟอื่น ๆ โดยตัวฝังตัว (Embedder) เฉพาะแพลตฟอร์มจะทำหน้าที่เป็นจุดเริ่มต้น ประสานงานกับระบบปฏิบัติการที่อยู่ภายใต้เพื่อเข้าถึงบริการต่างๆ เช่น พื้นผิวการแสดงผล การเข้าถึง และการป้อนข้อมูล และจัดการลูปเหตุการณ์ข้อความ ตัวฝังตัวเขียนด้วยภาษาที่เหมาะสมกับแพลตฟอร์ม ปัจจุบันคือ Java และ C++ สำหรับ Android, Swift และ Objective-C/Objective-C++ สำหรับ#jb iOS และ macOS และ C++ สำหรับ Windows และ Linux การใช้ตัวฝังตัว โค้ด Flutter สามารถรวมเข้ากับแอปพลิเคชันที่มีอยู่แล้วในรูปแบบโมดูล หรือโค้ดอาจเป็นเนื้อหาทั้งหมดของแอปพลิเคชันก็ได้ Flutter มีตัวฝังตัวจำนวนมากสำหรับแพลตฟอร์มเป้าหมายทั่วไป แต่ก็ยังมีตัวฝังตัวอื่นๆ อีกด้วย #iii หัวใจหลักของ Flutter คือ Flutter engine ซึ่งส่วนใหญ่เขียนด้วยภาษา C++ และรองรับฟังก์ชันพื้นฐานที่จำเป็นต่อการทำงานของแอปพลิเคชัน Flutter ทั้งหมด เอนจินนี้มีหน้าที่ในการแปลงฉากที่ประกอบขึ้นเป็นภาพแรสเตอร์ทุกครั้งที่จำเป็นต้องวาดเฟรมใหม่ มันมีหน้าที่ให้การใช้งานระดับต่ำของ API หลักของ Flutter รวมถึงการจัดวางข้อความกราฟิก การรับส่งข้อมูลไฟล์และเครือข่าย รันไทม์ Dart และเครื่องมือคอมไพล์ #iii เอนจินนี้ถูกเปิดเผยสู่เฟรมเวิร์ก Flutter ผ่านทาง dart:ui ซึ่งห่อหุ้มโค้ด C++ ที่อยู่เบื้องหลังด้วยคลาส Dart ไลบรารีนี้เปิดเผยส่วนประกอบพื้นฐานระดับต่ำสุด เช่น คลาสสำหรับควบคุมระบบย่อยการรับข้อมูล กราฟิก และการแสดงผลข้อความ #iii โดยทั่วไป นักพัฒนาจะโต้ตอบกับ Flutter ผ่านเฟรมเวิร์ก Flutter ซึ่งเป็นเฟรมเวิร์กที่ทันสมัยและตอบสนองต่อสิ่งรอบข้าง เขียนด้วยภาษา Dart เฟรมเวิร์กนี้ประกอบด้วยชุดไลบรารีแพลตฟอร์ม เลย์เอาต์ และพื้นฐานที่ครบครัน ซึ่งประกอบด้วยเลเยอร์หลายชั้น เริ่มจากล่างขึ้นบน ได้แก่: - คลาสพื้นฐานและบริการส่วนประกอบต่างๆ เช่น แอนิเมชัน การวาดภาพ และท่าทางสัมผัส ซึ่งนำเสนอนามธรรมที่ใช้กันทั่วไปเหนือพื้นฐานที่อยู่เบื้องหลัง - เลเยอร์การเรนเดอร์ให้นามธรรมสำหรับการจัดการเลย์เอาต์ ด้วยเลเยอร์นี้ คุณสามารถสร้างโครงสร้างแบบต้นไม้ของวัตถุที่เรนเดอร์ได้ คุณสามารถจัดการวัตถุเหล่านี้แบบไดนามิก โดยโครงสร้างแบบต้นไม้จะอัปเดตเลย์เอาต์โดยอัตโนมัติเพื่อสะท้อนการเปลี่ยนแปลงของคุณ - เลเยอร์วิดเจ็ตเป็นนามธรรมของการประกอบ วัตถุเรนเดอร์แต่ละชิ้นในเลเยอร์การเรนเดอร์จะมีคลาสที่สอดคล้องกันในเลเยอร์วิดเจ็ต นอกจากนี้ เลเยอร์วิดเจ็ตยังช่วยให้คุณกำหนดการรวมกันของคลาสที่คุณสามารถนำกลับมาใช้ใหม่ได้ นี่คือเลเยอร์ที่แนะนำโมเดลการเขียนโปรแกรมแบบตอบสนอง - ไลบรารี Material และ Cupertino นำเสนอชุดควบคุมที่ครอบคลุมซึ่งใช้ส่วนประกอบพื้นฐานของเลเยอร์วิดเจ็ตเพื่อนำภาษาการออกแบบ Material หรือ iOS ไปใช้ #iii เฟรมเวิร์ก Flutter มีขนาดค่อนข้างเล็ก ฟีเจอร์ระดับสูงหลายอย่างที่นักพัฒนาอาจใช้ถูกพัฒนาขึ้นมาในรูปแบบของแพ็กเกจ รวมถึงปลั๊กอินของแต่ละแพลตฟอร์ม เช่น กล้องและเว็บวิว ตลอดจนฟีเจอร์ที่ไม่ขึ้นกับแพลตฟอร์ม เช่น ตัวอักษร, HTTP และแอนิเมชัน ซึ่งสร้างขึ้นจากไลบรารีหลักของ Dart และ Flutter แพ็กเกจบางส่วนมาจากระบบนิเวศที่กว้างกว่า ครอบคลุมบริการต่างๆ เช่น การชำระเงินภายในแอป การตรวจสอบสิทธิ์ของ Apple และแอนิเมชัน #pagebreak() == โครงสร้างของแอปพลิเคชัน #iii แผนภาพต่อไปนี้แสดงภาพรวมของส่วนประกอบต่างๆ ที่ประกอบกันเป็นแอป Flutter ทั่วไปที่สร้างขึ้นโดยคำสั่ง `flutter create` แผนภาพนี้แสดงตำแหน่งของ Flutter Engine ในโครงสร้างนี้ เน้นขอบเขตของ API และระบุที่เก็บโค้ด (repository) ที่ส่วนประกอบแต่ละส่วนอยู่ คำอธิบายด้านล่างจะอธิบายคำศัพท์บางคำที่ใช้กันทั่วไปในการอธิบายส่วนประกอบของแอป Flutter #afigure( image("Flutter/app-anatomy.svg", width: 3in), attr: [Flutter, ภายใต้ CC BY 4.0], alt: "แผนผังสถาปัตยกรรม Flutter", caption: [สถาปัตยกรรม Flutter], ) - แอปพลิเคชัน Dart (Dart app) - ประกอบวิดเจ็ตเข้าด้วยกันเพื่อสร้าง UI ที่ต้องการ - ดำเนินการตามตรรกะทางธุรกิจ - นักพัฒนาแอปเป็นเจ้าของ - เฟรมเวิร์ก (Framework) - ให้ API ระดับสูงสำหรับการสร้างแอปคุณภาพสูง (ตัวอย่างเช่น วิดเจ็ต การทดสอบการกด#jb การตรวจจับท่าทาง การเข้าถึงได้ และการอินพุตข้อความ) - ประกอบต้นวิดเจ็ตของแอปพลิเคชันเป็นฉาก #pagebreak() - เอนจิน (Engine) - มีหน้าที่แปลงฉากเป็นรูปแบบแรสเตอร์ - ให้การทำงานระดับต่ำของแกนกลางของ Flutter API (เช่น กราฟิก การจัดข้อความ และรันไทม์ Dart) - เปิดเผยฟังก์ชันระดับนี้ให้แก่เฟรมเวิร์กผ่าน API `dart:ui` - บูรณาการกับแพลตฟอร์มต่าง ๆ ด้วย API ตัวฝังตัว - ตัวฝังตัว (Embedder) - ประสานงานกับระบบปฏิบัติการภายใต้สำหรับการเข้าถึงบริการต่าง ๆ เช่น พื้นผิวการเรนเดอร์ การเข้าถึง และการป้อนข้อมูล - จัดการลูปอิเวนต์ - เปิดเผย API เฉพาะแพลตฟอร์มเพื่อบูรณาการตัวฝังตัวเข้าไปยังแอป - ตัวรัน (Runner) - ประกอบชิ้นส่วนที่ถูกเปิดเผยโดยตัวฝังตัวเข้าเป็นแพคเกจแอปพลิเคชันที่สามารถใช้งานได้บนแพลตฟอร์มเป้าหมาย - บางส่วนถูกสร้างขึ้นโดย `flutter create` และมีเจ้าของเป็นผู้พัฒนาแอป == ระบบการดีไซน์ #iii โดยใน Flutter แล้วนั้น ไม่รวมแพคเกจบุคคลที่สาม จะมีระบบการดีไซน์อยู่สองแบบคือ: #[ #set enum(indent: 5.5em) + Material Design: การดีไซน์ของ Google สำหรับ Android + Cupertino Design: การดีไซน์ของ Apple สำหรับ iOS ] #iii *หมายเหตุ:* Cupertino Design ถูกแทนที่โดย Liquid Glass แล้ว โดยในปัจจุบันทีม Flutter กำลังทำการตรวจสอบและแก้ไขโครงสร้างระบบดีไซน์ ดังนั้น หากมีผู้พัฒนาต้องการใช้เอฟเฟกต์#jb Liquid Glass ในแอปพลิเคชัน Flutter จึงจำเป็นต้องพึงพาแพคเกจบุคคลที่สามก่อนในขณะนี้ (Flutter เวอร์ชัน 3.38.5 ณ เวลาที่พิมพ์) #iii Material Design คือภาษาการดีไซน์ที่ถูกพัฒนาโดย Google และถูกเปิดตัวครั้งแรก 25 มิถุนายน 2014 และมีเวอร์ชันหลัก 3 เวอร์ชันด้วยกัน โดยที่เวอร์ชันที่ 3 ถูกเปิดตัวในงาน Google I/O 2021 และมีชื่อว่า "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/ == ส่วนติดต่อผู้ใช้ที่มีปฏิกิริยา #iii บนพื้นผิว Flutter เป็นเฟรมเวิร์ก UI แบบ reactive และ declarative ซึ่งนักพัฒนาเป็นผู้จัดเตรียมการแมปจากสถานะแอปพลิเคชันไปยังสถานะอินเทอร์เฟซ และเฟรมเวิร์กจะทำหน้าที่อัปเดตอินเทอร์เฟซขณะรันไทม์เมื่อสถานะของแอปพลิเคชันเปลี่ยนแปลง โมเดลนี้ได้รับแรงบันดาลใจจากงานที่มาจาก Facebook สำหรับเฟรมเวิร์ก React ของพวกเขา ซึ่งรวมถึงการทบทวนหลักการออกแบบแบบดั้งเดิมหลายประการ #iii ในเฟรมเวิร์ก UI แบบดั้งเดิมส่วนใหญ่ สถานะเริ่มต้นของอินเทอร์เฟซผู้ใช้จะถูกอธิบายเพียงครั้งเดียว จากนั้นจึงอัปเดตแยกกันด้วยโคดผู้ใช้ ณ รันไทม์ เพื่อตอบสนองต่อเหตุการณ์ ความท้าทายประการหนึ่งของแนวทางนี้คือ เมื่อแอปพลิเคชันมีความซับซ้อนมากขึ้น นักพัฒนาจำเป็นต้องทราบว่าสถานะเปลี่ยนแปลงไปอย่างไรตลอดทั้ง UI ตัวอย่างเช่น พิจารณา UI ต่อไปนี้: #afigure( image("Flutter/color-picker.png", width: 70%), alt: "หน้าต่างเลือกสี", caption: [หน้าต่างเลือกสี], ) #iii มีหลายที่ที่สามารถเปลี่ยนสถานะได้: กล่องสี, แถบเลื่อนเฉดสี, ​​ปุ่มตัวเลือก เมื่อผู้ใช้โต้ตอบกับ UI การเปลี่ยนแปลงจะต้องสะท้อนให้เห็นในทุกที่ ที่เลวร้ายยิ่งกว่านั้น เว้นแต่จะได้รับการดูแล การเปลี่ยนแปลงเล็กน้อยในส่วนใดส่วนหนึ่งของอินเทอร์เฟซผู้ใช้อาจทำให้เกิดเอฟเฟกต์คลื่นส่งผลกระทบกับโค้ดที่ดูเหมือนจะไม่เกี่ยวข้องกัน #iii วิธีแก้ปัญหาอย่างหนึ่งคือแนวทางเช่น MVC โดยที่คุณส่งข้อมูลการเปลี่ยนแปลงไปยังโมเดลผ่านคอนโทรลเลอร์ จากนั้นโมเดลจะพุชสถานะใหม่ไปยังมุมมองผ่านคอนโทรลเลอร์ อย่างไรก็ตาม#jb สิ่งนี้ก็เป็นปัญหาเช่นกัน เนื่องจากการสร้างและการอัปเดตองค์ประกอบ UI เป็นขั้นตอนสองขั้นตอนที่แยกจากกันซึ่งอาจไม่ซิงค์กันได้อย่างง่ายดาย #iii Flutter พร้อมด้วยเฟรมเวิร์กเชิงโต้ตอบอื่น ๆ ใช้แนวทางอื่นในการแก้ไขปัญหานี้ โดยแยกอินเทอร์เฟซผู้ใช้ออกจากสถานะพื้นฐานอย่างชัดเจน ด้วย API สไตล์ React คุณจะสร้างเฉพาะคำอธิบาย UI เท่านั้น และเฟรมเวิร์กจะดูแลการใช้การกำหนดค่านั้นเพื่อสร้างหรืออัปเดตอินเทอร์เฟซผู้ใช้ตามความเหมาะสม #iii ใน Flutter วิดเจ็ต (คล้ายกับส่วนประกอบใน React) จะแสดงด้วยคลาสที่ไม่เปลี่ยนรูปซึ่งใช้ในการกำหนดค่าแผนผังของวัตถุ วิดเจ็ตเหล่านี้ถูกใช้เพื่อจัดการแผนผังวัตถุที่แยกจากกันสำหรับโครงร่าง ซึ่งจากนั้นจะใช้ในการจัดการแผนผังวัตถุที่แยกจากกันสำหรับการประกอบ หัวใจหลักของ Flutter คือชุดของกลไกในการอัพเดทส่วนที่ดัดแปลงของแผนผังวิดเจ็ตอย่างมีประสิทธิภาพ การแปลงแผนผังหลายแผนผังของวัตถุให้เป็นแผนผังระดับล่างของวัตถุ และการแพร่กระจายการเปลี่ยนแปลงไปยังแผนผังวิดเจ็ตเหล่านี้ #iii วิดเจ็ตประกาศส่วนติดต่อผู้ใช้โดยการเขียนทับเมธอด `build()` ซึ่งเป็นฟังก์ชันที่แปลงสถานะเป็น UI: #afigure( ``` UI = f(state) ```, kind: image, caption: [สูตรแสดงการทำงานอย่างคร่าว], ) #iii เมธอด `build()` นั้นตามการออกแบบแล้วเป็นเมธอดที่เร็วและควรที่จะไม่มีผลข้างเคียง ทำให้เมธอดนั้นสามารถถูกเรียกใช้โดยเฟรมเวิร์กเมื่อไหร่ก็ได้ที่จำเป็น (เป็นไปได้ที่จะบ่อยมากและมีการเรียกใช้หนึ่งครั้งต่อหนึ่งเฟรม) #iii วิธีนี้พึ่งพาลักษณะเฉพาะรันไทม์ภาษา (หากเจาะจงคือการสร้างและทำลายวัตถุอย่างรวดเร็ว) ซึ่ง Dart นั้นเหมาะสำหรับงานนี้เป็นพิเศษ == ประวัติ #iii Flutter เวอร์ชันแรกรู้จักกันในชื่อ "Sky" และทำงานบนระบบปฏิบัติการ Android มีการเปิดเผยในการประชุมสุดยอดนักพัฒนา Dart ประจำปี 2015 โดยมีจุดประสงค์ที่ระบุไว้คือสามารถแสดงผลได้อย่างสม่ำเสมอที่ 120 เฟรมต่อวินาที เมื่อวันที่ 4 ธันวาคม 2018 Flutter 1.0 เปิดตัวในการประชุม Flutter ที่ลอนดอน #iii ในวันที่ 6 พฤษภาคม 2020 ชุดพัฒนาซอฟต์แวร์ (SDK) Dart เวอร์ชัน 2.8 และ Flutter 1.17.0 ได้รับการเผยแพร่ โดยเพิ่มการรองรับ Metal API #iii เมื่อวันที่ 3 มีนาคม 2021 Google ได้เปิดตัว Flutter 2 ระหว่างกิจกรรม Flutter Engage ออนไลน์ ได้เพิ่มตัวเรนเดอร์ที่ใช้ Canvas สำหรับเว็บ นอกเหนือจากตัวเรนเดอร์ที่ใช้ HTML และการสนับสนุนแอปพลิเคชันเดสก์ท็อปแบบทดลองสำหรับ Windows, macOS, และ Linux นอกจากนี้ยังมาพร้อมกับ Dart 2.0 ซึ่งรวมถึงการสนับสนุนด้านความปลอดภัยแบบ null (null-safety) ความปลอดภัยแบบ null เป็นทางเลือกในตอนแรกเนื่องจากเป็นการเปลี่ยนแปลงครั้งใหญ่และบังคับใช้ใน Dart 3 ที่เปิดตัวในปี 2023 #iii ในวันที่ 12 พฤษภาคม 2022 Flutter 3 และ Dart 2.17 ได้รับการเผยแพร่โดยมีการรองรับแพลตฟอร์มเดสก์ท็อปทั้งหมดอย่างเสถียร #iii เมื่อวันที่ 27 ตุลาคม 2024 นักพัฒนาชุมชน Flutter จำนวนหนึ่งได้ประกาศเปิดตัว Flock ซึ่งเป็นเวอร์ชันแยกของ Flutter ที่มีจุดประสงค์เพื่อให้ง่ายต่อการร่วมพัฒนา ในขณะเดียวกันก็ยังคงรักษาความสอดคล้องกับทุกการเปลี่ยนแปลงที่เกิดขึ้นในโค้ดต้นทาง #iii ในปี 2025 Google ยังคงพัฒนา Flutter ต่อไปด้วยสถาปัตยกรรมแบบโมดูลาร์ที่ได้รับการปรับปรุง การรองรับอุปกรณ์พับได้ และการเพิ่มประสิทธิภาพ ARM IoT ตามที่ระบุไว้ในแผนงานฉบับปรับปรุง