Layout
โดยวันนี้ ผมจะมาพูดถึงการจัดการ Widget ของ Flutter ด้วย Widget ที่ใช้สำหรับจัดการ Widget หลายๆตัวโดยทั้วไปแล้วนั้นจะมีด้วยกันหลาย Widget ตัวอย่างเช่น
แต่สำหรับบทความนี้ผมจะพูดถึงแค่ Row และ Column ซึ่งถือว่ามีประโยชน์มากๆ ในการจัดการ Layout ของ App ที่เราจะสร้าง แต่บางครั้งก็สามารถสร้างความสับสนให้กับเราได้ด้วยเหมือนกัน
Column
การจัดการ Layout ด้วย Widget Column คือการจัดการ Widget ให้ซ้อนทับกันในแนวตั้ง ก่อนอื่นเราต้องสร้าง project flutter ขึ้นมาก่อน โดยผมถนัดที่จะใช้คำสั่งมากกว่า การสร้าง Project บน android studio นะครับ โดย้คำสั่งดังนี้
flutter create --org com.wo layout
หลังจากนั้นก็ทำการ ลบ code ที่เราไม่จำเป็นต้องใช้ให้เหลือ Code ดังต่อไปนี้
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(title: 'Flutter Layout'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Container());
}
}
พอเราทำการ run app ก็จะได้ผลลัพธ์แบบรูปด้านล่างนี้
หลังจากนั้นเราลองมาทำความเข้าใจ การใช้งาน Widget Column กันขั้นต้นกันก่อน การจัดการ Widget หลายๆตัวนั้น เราสามารถใช้ Widget parent ได้หลายตัวแต่ถ้าเราต้องการจัดการ widget ให้จัดเรียงและอยู่กันในแนวตั้ง เราควรเลือกใช้ Widget Column โดยผมจะแสดงการเรียงด้วย code ด้านล่างนี้ ให้เราทำกการเพิ่ม code ลงไปใน body
ผมได้สร้าง Widget Box ขึ้นมาให้ โดยมี parameter color เพื่อจะให้สามารถกลับมาใช้งานใหม่ได้ดังนี้
Widget box({Color color = Colors.red}) {
return Container(
width: 100,
height: 100,
color: color,
);
}
หลังจากนั้นใช้ Widget Column ใน argument body
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Column(
children: [
box(color: Colors.red),
box(color: Colors.yellow),
box(color: Colors.green),
],
),
);
โดยจะเรียกใช้งาน Widget box ที่เราสร้างขึ้นใหม่ทั้งหมด 3 box โดยให้แต่ละ box นั้นมีสีที่แตกต่างกันผลลัพธ์ที่ ดังที่แสดงตามรูปด้านล่างนี้
เราจะเห็นว่า widget box ทั้ง 3 อันนั้น เรียงต่อกันในแนวตั้ง เมื่อเราจัดเรียงด้วย widget column นอกจากนั้นเรายังสามารถปรับแต่ง Layout ต่างๆได้ดังนี้ โดยเราเริ่มที่ parameter mainAxisAlignment คือหมายถึงจากจัดการในแนวตั้งซึ่งเป็นแนวเดียวกันกับ Column ดังนี้
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
box(color: Colors.red),
box(color: Colors.yellow),
box(color: Colors.green),
],
),
MainAxisAlignment.center
|
MainAxisAlignment.center |
MainAxisAlignment.start
|
MainAxisAlignment.start |
MainAxisAlignment.end
|
MainAxisAlignment.end |
MainAxisAlignment.spaceAround
|
MainAxisAlignment.spaceAround |
MainAxisAlignment.spaceBetween
|
MainAxisAlignment.spaceBetween |
MainAxisAlignment.spaceEvenly
|
MainAxisAlignment.spaceEvenly |
เมื่อเราดำเนินการจัดการ Layout ของ Widget Column ด้วย property mainAxisAlignment ซึ่งคือทิศทางเดียวกันกับ widget column หรือในแนวตั้ง ต่อไปนี้เราจะทำการจัด Layout ที่อีกทิศทางนึงคือใน ทิศทางที่เป็นแนวนอน หรือ CrossAxisAlignment แต่เราต้องทำการเพิ่ม Widget parent เข้าไปอีก 1 widget นั่นคือ Container เหตุผลที่เราต้องเพิ่ม widget parent เข้าไปอีก 1 widget ก็เพราะว่าตอนนี้ widget column นั้นห่อหุ้ม widget box ของเราไว้อยู่ ซึ่งถ้าเราทำการจัด layout ด้วย CrossAxisAlignment นั้นไม่เห็นผลอะไร โดยเราต้องทำการเพิ่ม code ใหม่เข้าไปดังนี้
body: Container(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
box(color: Colors.red),
box(color: Colors.yellow),
box(color: Colors.green),
],
),
),
หลังจากนี้เราลองทดลอง ปรับค่า parameter CrossAxisAlignment โดยผมจะทำการคงค่า mainAxisAlignment.spaceEvenly ไว้
CrossAxisAlignment.start
|
CrossAxisAlignment.start |
CrossAxisAlignment.center
|
CrossAxisAlignment.center |
CrossAxisAlignment.end
|
CrossAxisAlignment.end |
CrossAxisAlignment.stretch
|
CrossAxisAlignment.stretch |
ตัวอย่างด้านบนนี้คือการจัด Layout ของ Widget Column ซึ่งต้องขึ้นอยู่กับว่านักพัฒนาจะนำไปปรับแก้อย่างไรใน app ของตัวเอง ต่อไปผมจะแสดงตัวอย่าง การจัด Layout ของ Widget Row ซึ่งจะคล้ายๆกับ Column แต่จะมีทิศทางในทางตรงกันข้าม
Row
Row คือ widget ที่จัดการ layout ของหลายๆ widgetในแนวนอน (horizontal) โดยจะสามารถปรับแต่ง layout ได้ทั้งแนวตั้งและแนวนอนคล้ายๆกับ widget ของ Column โดยเราใช้ code ที่เหมือนกับ widget column ด้านบน แต่ให้เราแก้ไข จาก column เป็น row ดังนี้
body: Container(
width: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
box(color: Colors.red),
box(color: Colors.yellow),
box(color: Colors.green),
],
),
),
และลองตั้งค่า MainAxisAlignment เป็น start
MainAxisAlignment.start
|
MainAxisAlignment.start |
MainAxisAlignment.center
|
MainAxisAlignment.center |
MainAxisAlignment.end
|
MainAxisAlignment.end |
MainAxisAlignment.spaceAround
|
MainAxisAlignment.spaceAround |
MainAxisAlignment.spaceBetween
|
MainAxisAlignment.spaceBetween |
MainAxisAlignment.spaceEvenly
|
MainAxisAlignment.spaceEvenly |
ต่อเป็นจะทำการจัดหน้า Layout ด้วย parameter crossAxisAlignment คือการ layout ในทิศทาง ตั้งฉากกับ Row widget ซึ่ง row widget นั้นเป็นการจัดการ widget ในแนวนอน (horizontal) ถ้าเราใช้ crossAxisAlignment ก็คือการจัดการ widget ในแนวตั้งนั่นเอง เราจะทำคล้ายๆกับ widget Columm ด้านบนแต่เราจะคงค่า mainAxisAlignment.spaceAround ไว้
แต่ก่อนอื่น เราต้องปรับแก้ parameter ของ parent widget เสียก่อน โดยเปลี่ยนจาก width เป็น height เพื่อไม่ให้ห่อหุ้ม widget row ของเราไว้ เพื่อให้ parent widget นั้นขยายเต็มหน้าจอ
body: Container(
height: double.infinity,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
box(color: Colors.red),
box(color: Colors.yellow),
box(color: Colors.green),
],
),
),
CrossAxisAlignment.start
|
CrossAxisAlignment.start |
CrossAxisAlignment.center
|
CrossAxisAlignment.center |
CrossAxisAlignment.end
|
CrossAxisAlignment.end |
CrossAxisAlignment.stretch
|
CrossAxisAlignment.stretch |
จากตัวอย่างด้านบนนี้คือการจัด Layout ด้วย widget Row และ Column ซึ่งผู้ที่สนใจสามารถนำไปปรับแก้ให้เขากับ app หรือ web กำลังพัฒนาอยู่นะครับ หวังว่า จะมีประโยชน์กับผู้ที่สนใจนะครับ