Flutter Application Development


รู้จักฟลัตเตอร์

ฟลัตเตอร์คืออะไร

ฟลัตเตอร์ คือเฟรมเวิร์คที่พัฒนาโดยกูเกิล ใช้สำหรับสร้างแอปครั้งเดียวแต่ทำงานได้บนหลายระบบ เช่นไอโอเอส iOS, iPhone, iPad หรือเอนดรอยด์ Android phones

Flutter Architecture


Flutter


ทุกอย่างในฟลัตเตอร์คือวิดเจ็ต Widget โดยเราเขียนโปรแกรมสร้างวิดเจ็ตด้วยภาษา Dart ที่พัฒนาโดยกูเกิลเช่นเดียวกัน

Dart


ความเกี่ยวข้องระหว่างฟลัตเตอร์กับดาร์ท

Flutter and Dart


วิดเจ็ตหลักที่แสดงผลบนหน้าจอคือ scaffold (คล้ายกับ view ในไอโอเอส) ซึ่งเราจะวางวิดเจ็ตอื่นๆไว้บน scaffold
scaffold คือวิดเจ็ตหน้าจอ page widget คือทุกอย่างที่แสดงผลในหนึ่งหน้าจอ ซึ่งประกอบด้วยหลายๆวิดเจ็ตใน scaffold เช่น Text, Button, Appbar, List, ListItem, Image ตามรูป

Flutter Apps and Widget


ในการสร้างวิดเจ็ต widget เราต้องสร้างคลาส class ขึ้นมาก่อน คือคลาสใช้สร้างวิดเจ็ตนั่นเอง หรือวิดเจ็ตคือวัตถุ object ชิ้นหนึ่ง วัตถุทุกอันในโปรแกรมจะถูกสร้างมาจากคลาส
object widget ค่อนข้างซับซ้อน เพราะต้องจัดการแแสดงผลทั้งหมดในหน้าจอ ซึ่งขั้นตอนนี้ฟลัตเตอร์เฟรมเวิร์คจะจัดการให้ เราแค่สร้างวิดเจ็ต ฟลัตเตอร์จะแสดงผลวิดเจ็ตให้เราเอง คือทำการลากเส้นต่อจุด pixels ทุกจุดบนหน้าจอที่ใช้ในการสร้างวิดเจ็ตนั้นๆ
การสร้างคลาส
class MyApp {

}
การสร้างวิดเจ็ตจากฟังก์ชันเมน main()
ฟลัตเตอร์มีเมธอดชื่อ runApp() ที่ใช้สร้างวิดเจ็ตของแอป
วิดเจ็ต MyApp() สืบทอดจาก StatelessWidget ทำให้สามารถเรียกใช้เมธอด build() เพื่อสร้างวิดเจ็ตทั้งหมดในแอปโดยใช้ วิดเจ็ต MaterialApp() ซึ่งภายในวิดเจ็ต MaterialApp() ก็ให้เราสร้างวิดเจ็ตอื่นๆตามที่เราต้องการ ตามตัวอย่างคือสร้าง Text() วิดเจ็ตให้แสดงข้อความ 'Hello'
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Text('Hello'),
    );
  }
}

flutter2


Dart

ฟลัตเตอร์ใช้ภาษา Dart ในการสร้างแอป
โครงสร้างของภาษา Dart จะคล้ายกับภาษา C++, C# หรือ Java
สร้่งคลาส Person() ด้วยพารามิเตอร์หรืออากิวเมนต์ตามตำแหน่ง positional argument และเมธอด addNumbers()

 
  class Person {
    String name;
    int age;
    Person(String n, int age) {  // พารามิเตอร์หรืออากิวเมนต์ตามตำแหน่ง positional argument
      name = n;
      this.age = age;
    }
    void display() {
      print('I am $name, $age years old.');  // $name หมายถึงค่าของตัวแปร
    }
  }
  num addNumbers(num x, num y) {
    return x+y;
  }
  void main() {
    var x = addNumbers(2.1,8.5);
    print('hello: $x');
    x = addNumbers(200.1,800.5);
    print(x+.4);
    Person p = Person('deen', 22);
    p.display();
  }
  ผลลัพธ์
  hello: 10.6
  1001
  I am deen, 22 years old.

สร้่างคลาส Person() ด้วยพารามิเตอร์หรืออากิวเมนต์ตามชื่อ name argument ภายในวงเล็บปีกกา {}
การประกาศแบบนี้ทำให้พารามีเตอร์ทั้งหมดเป็น optional คือไม่บังคับว่าต้องส่งพารามีเตอร์มายังเมธอด
name argument เหมาะสำหรับเมธอดที่มีพารามีเตอร์จำนวนมาก เราเลือกใช้เฉพาะพารามีเตอร์ที่ต้องการได้
สามารถบังคับว่าต้องใช้พารามิเตอร์บ้างด้วยคีย์เวิร์ด @reqquired
สามารถกำหนดค่าเริ่มต้นให้กับพารามิเตอร์ตัวสุดท้ายได้ด้วยเครื่องหมาย = เพิ่อป้องกันข้อผิดพลาดกรณีไม่ส่งพารามิเตอร์ใดๆเลย

class Person {
  String name;
  int age;
  // optional พารามิเตอร์หรืออากิวเมนต์ตามชื่อ name argument ครอบอาร์กิวเมนต์ด้วย {} 
  // default parameter age = 20
  // required parameter @required String name 
  // dart ไม่มี @required แต่ flutter มี
  Person({@required String name, int age = 20}) { 
    this.name = name; // ชื่อเหมือนกัน ใช้ this เพื่ออ้างอิงถึงตัวแปรภายในคลาส
    this.age = age;
  }
  void display() {
    print('I am $name, $age years old.');
  }
}
void main() {
  Person p = Person(name:'deen', age:33); // กำหนดชื่อ ตามด้วยค่า
  p.display();
  Person p2 = Person(age:22, name:'dmm'); // ตำแหน่งไม่สำคัญ สลับกันได้ แต่ชื่อต้องตรงกัน 
  p2.display();
}
ผลลัพธ์
I am deen, 33 years old.
I am dmm, 22 years old.

shortcut constructor
ใช้ชื่อตัวแปรของคลาสแทนชื่อพารามีเตอร์ของ constructor ได้เลย

  class Person {
    String name;
    int age;
    Person({this.name, this.age = 20});  // ปิด constructor ด้วย ;
    void display() {
      print('I am $name, $age years old.');
    }
  }
  void main() {
    Person p = Person(name:'noor', age:22); // กำหนดชื่อ ตามด้วยค่า
    p.display();
    Person p2 = Person(name:'ty'); // ตำแหน่งไม่สำคัญ สลับกันได้ แต่ชื่อต้องตรงกัน ใช่ defaut age
    p2.display();
  }
  ผลลัพธ์
  I am noor, 22 years old.
  I am ty, 20 years old.
  

สรุปการทำงานของฟลัตเตอร์และดาร์ท

  import 'package:flutter/material.dart';
  
  void main() {
    runApp(MyApp());
  }
  
  class MyApp extends StatelessWidget {
    @override   // ไม่ใส่ก็ได้
    Widget build(BuildContext context) {
      return MaterialApp(
        home: Text('Hello'),
      );
    }
  }
  

Dart เริ่มต้นรันโปรแกรมที่ฟังก์ชันเมน main() ซึ่งเรียกเมธอด runApp() จากคลาส material.dart เพื่อบอกฟฟลัตเตอร์ให้สร้างวิดเจ็ต MyApp()
MyApp() ต้องสร้างเมธอด build() หรือ @override build() แต่ไม่จำเป็นต้องใส่ @override เพราะค่าเริ่มต้นของเมธอด build() คือต้อง override หรือต้องสร้างอยู่แล้ว เพื่อบอกให้ฟลัตเตอร์สร้างวิดเจ็ตตามที่กำหนดและให้รีเทินวิดเจ็ตกลับไปยังเมนเพื่อแสดงผล
เราสร้างวิดเจ็ตในเมธอด build() ด้วย constructor ของคลาส MaterailApp() ซึ่งเราส่งพารามิเตอร์ให้สร้างวิดเจ็ต Text() ให้แสดงข้อความ Hello ผ่านทาง name argument ชื่อ home:
ส่วนพารามิเตอร์ของเมธอด build() คือ context หมายถึงหน้าจออุปกรณ์ที่ใช้แสดงผลซึ่งฟลัตเตอร์จะจัดการแสดงผลตามอุปกรณ์นั้นๆ โดยเราไม่ต้องสร้าง context เพื่อส่งไปยังเมธอด build()
ส่วนพารามิเตอร์ MyApp() ที่ส่งไปยังเมธอด runApp() หมายถึงการสร้าง concrete class MyApp() หรือวิดเจ็ตนั่นเอง
เช่นเดียวกับ shortcut constructor เราสามารถสร้าง sshortcut main() สำหรับเมนที่มีเพียงหนึ่งคำสั่งภายในเมน ในกรณีนี้อคือคำสั่ง runApp() ซึ่งทำได้ดังนี้

  import 'package:flutter/material.dart';
  
  // void main() {
  //  runApp(MyApp());
  // }
  void main() => runApp(MyApp());   // เอาวงเล็บปีกกาออก ใส่เครื่องหมาย => แล้วปิดท้ายคำสั่งด้วย ;

  class MyApp extends StatelessWidget {
    @override   // ไม่ใส่ก็ได้
    Widget build(BuildContext context) {
      return MaterialApp(
        home: Text('Hello'),
      );
    }
  }
  

2020. mnet50.com