Flutter: Flexible vs Expanded
Published on
Authored by Pete. Pittawat Taveekitworachai.
บางครั้งเราต้องการให้ Widget ของเรา Take space ที่เหลือทั้งหมดของ Column
/Row
นั้น ๆ หรือ เราอาจต้องการให้ Widget แต่ละส่วนใน Column
/Row
ใช้ Space เท่า ๆ กัน แน่นอนว่า Widget 2 ตัว ที่มักถูกใช้รับมือกับสถานการณ์แบบนี้ คงหนีไม่พ้น Flexible
และ Expanded
แล้วทั้งสองตัวนี้ต่างกันอย่างไร?
Flexible
Flexible
ใช้สำหรับทำให้ Child Widget ขยายจนเต็มพื้นที่ว่างที่เหลืออยู่ตามแกนหลัก (Main Axis เช่น Row
จะเป็นแนวนอน หากเป็น Column
จะเป็นแนวตั้ง) แต่ไม่บังคับ นั่นคือเราอาจตั้งให้ Child ตัวนั้นมีค่าของ width
/height
ไว้ก็ได้ โดย Properties ที่สำคัญของ Flexible
คือ fit
ซึ่งใช้สำหรับบอกว่าจะให้ Child Widget จัดการกับพื้นที่อย่างไร โดย fit
ต้องการค่าประเภท FlexFit
ซึ่งมีอยู่ด้วยกัน 2 แบบ คือ FlexFit.loose
และ FlexFit.tight
ซึ่งโดย Default จะเป็น FlexFit.loose
ซึ่งไม่บังคับว่า Child Widget ต้องใช้ Space ทั้งหมด โดยอาจมีขนาดใดก็ได้ที่ใหญ่ที่สุดเท่ากับที่ว่างที่เหลือ หรือเล็กกว่านั้น ในขณะที่ FlexFit.tight
จะบังคับให้ Child Widget ใช้พื้นที่ทั้งหมดที่เหลืออยู่
นอกจากนี้ Flexible
ยังมีประโยชน์ในกรณีที่เราต้องการแบ่งพื้นที่ออกเป็นอัตราส่วนต่าง ๆ ได้ด้วย ด้วย Property flex
ซึ่งมีค่า Default เป็น 1
เราสามารถตั้งให้เป็นเลขต่าง ๆ เพื่อให้เกิดการคำนวณตามอัตราส่วนได้อีกด้วย เมื่อใช้คู่กับ Flexible
ตัวอื่น
โดยการคำนวณพื้นที่ของ flex
จะหาพื้นที่ทั้งหมดที่ใช้ได้มาลบกับพื้นที่ของ Widget ที่ Inflexible (Widget ที่มีขนาดแบบ Static เช่น การกำหนด width
/height
โดยตรง) จากนั้นจะนำมาหารตามอัตราส่วน เช่น หากมี Flexible
2 อัน อันแรกกำหนด flex: 1
อันที่ 2 กำหนด flex: 2
และมี Container
อีกหนึ่งอันที่กำหนด width: 50
อยู่ใน Row
เดียวกัน สมมติว่าเรามีพื้นที่งหมดที่เป็นไปได้เท่ากับ 350 ตามแนวนอน
การคำนวณจะเริ่มจากการนำ 350 มาตั้ง ลบด้วยขนาดตามแกนหลัก ซึ่งในที่นี้ คือ แนวนอน (width
) ของ Inflexible Widget มาลบ ซึ่งเรามีหนึ่งอันคือ Container
ที่มี width: 50
ทำให้เราเหลือพื้นที่ที่จะนำมาหารเท่ากับ 300 จากนั้น เราจะไปดูว่า flex
รวมกันเท่ากับเท่าไร ซึ่งเรามี flex: 1
และ flex: 2
รวมกันเท่ากับ 3 เราจึงนำ 300 / 3 = 100 นั่นแปลว่า 1 ส่วนของพื้นที่เท่ากับ 100 เราจะให้พื้นที่ตามอัตราส่วนของแต่ละ Widget โดย Flexible
ที่มี flex: 1
จะได้ width เท่ากับ 100 ส่วน Flexible
ที่มี flex: 2
จะได้ width เท่ากับ 200 นั่นเอง
Expanded
แล้ว Expanded
ละ คือ อะไร คำตอบ คือ มันคือ Flexible
ที่มี fit: FlexFit.tight
นั่นเอง นั่หมายความว่า Expanded
ทำได้ทุกอย่างเหมือน Flexible
แต่บังคับให้ Child Widget ต้องใช้พื้นที่ที่ว่างทั้งหมดนั่นเอง