Flexible คือวิดเจ็ต Flutter ที่ควบคุมว่าองค์ประกอบลูกจะใช้พื้นที่ว่างในคอนเทนเนอร์ Flex อย่างไร แตกต่างจาก Expanded ตรงที่ Flexible ไม่บังคับให้ลูกเติมเต็มพื้นที่ทั้งหมดที่จัดสรรไว้ — วิดเจ็ตลูกสามารถมีขนาดเล็กกว่าได้ และพื้นที่ที่เหลือจะว่างเปล่า ตามเอกสารทางการของ Flutter (2026) Flexible จำเป็นในสถานการณ์ที่ต้องการการกระจายพื้นที่อย่างยืดหยุ่นโดยไม่ต้องยืดแบบบังคับ: ปุ่มที่มีความกว้างขั้นต่ำ บล็อกข้อความที่มีขนาดธรรมชาติ และองค์ประกอบที่มี intrinsic constraints
ประเด็นสำคัญ
Flexible คือวิดเจ็ตหุ้มที่ให้พื้นที่ยืดหยุ่นแก่องค์ประกอบลูกในคอนเทนเนอร์ Flex Flexible เช่นเดียวกับ Expanded มีส่วนร่วมในการกระจายพื้นที่ว่าง แต่มีความแตกต่างที่สำคัญ: ลูกของ Flexible สามารถใช้พื้นที่น้อยกว่าที่จัดสรรได้หากขนาดของมันเล็กกว่าพื้นที่ว่าง
Flexible ใช้อัลกอริทึม Flex ของ Flutter เพื่อคำนวณพื้นที่ว่าง อันดับแรก เฟรมเวิร์กจะสอบถามลูกที่ไม่ยืดหยุ่นทั้งหมด (วิดเจ็ตที่ไม่มี Flexible/Expanded) และคำนวณขนาดภายในของ它们 จากนั้นพื้นที่ที่เหลือจะถูกแบ่งระหว่างลูกที่ยืดหยุ่นตามสัดส่วนของแฟกเตอร์ flex หลังจากการจัดสรรพื้นที่ Flexible จะตรวจสอบ fit — ถ้าเป็น loose ลูกจะได้รับข้อจำกัด “ไม่ใหญ่กว่าที่จัดสรร” ทำให้มันสามารถคงขนาดเล็กไว้ได้
คุณลักษณะของ Flexible: ถ้าวิดเจ็ตลูกมีขนาดต่ำสุดของตัวเอง (เช่น ข้อความที่มีสตริงยาว) Flexible จะจัดสรรพื้นที่ตามที่ร้องขอโดยไม่ต้องยืดแบบบังคับ สิ่งนี้ทำให้ Flexible ขาดไม่ได้สำหรับองค์ประกอบที่ขนาดควรถูกกำหนดโดยเนื้อหา而不是โดยคอนเทนเนอร์
สรุป: ใช้ Flexible เมื่อคุณต้องการสงวนพื้นที่สำหรับองค์ประกอบแต่ไม่ต้องการบังคับให้ยืด สิ่งนี้รักษาขนาดธรรมชาติของเนื้อหาในขณะที่คงการกระจายเลย์เอาต์ที่ยืดหยุ่น
FlexFit คือการแจงนับของสองค่า: tight และ loose การเลือก fit จะกำหนดว่าวิดเจ็ตลูกจะถูกยืดแบบบังคับให้มีขนาดเท่ากับพื้นที่ที่จัดสรรหรือไม่
FlexFit.tight: องค์ประกอบลูกได้รับ tight constraints — ขนาดต่ำสุดและสูงสุดเท่ากับพื้นที่ที่จัดสรร ลูกต้องใช้พื้นที่เท่ากับที่อัลกอริทึม Flex จัดสรรไว้พอดี ถ้าลูกเล็กกว่า — มันจะถูกยืด ถ้าใหญ่กว่า — มันจะถูกหด พฤติกรรมเหมือนกับ Expanded
FlexFit.loose: องค์ประกอบลูกได้รับ loose constraints — ขนาดต่ำสุดคือ 0 ขนาดสูงสุดเท่ากับพื้นที่ที่จัดสรร ลูกสามารถมีขนาดใดก็ได้ตั้งแต่ 0 ถึงสูงสุด ถ้าลูกเล็ก (เช่น ข้อความที่มีสตริงสั้น) มันจะใช้ความกว้างตามธรรมชาติและพื้นที่ที่เหลือจะว่างเปล่า
สรุป: FlexFit.loose คือตัวเลือกสำหรับบล็อกข้อความและองค์ประกอบที่มีขนาดธรรมชาติ FlexFit.tight สำหรับเลย์เอาต์คอลัมน์ที่เข้มงวดซึ่งองค์ประกอบทั้งหมดต้องมีความกว้างหรือความสูงเท่ากัน
Flexible และ Expanded ดูคล้ายกันแต่แก้ไขงานที่แตกต่างกัน Expanded ยืดลูกเสมอเพื่อเติมเต็มพื้นที่ว่างทั้งหมด Flexible สามารถเว้นที่ว่างรอบๆ ลูกได้หากขนาดเนื้อหาเล็กกว่าส่วนที่จัดสรร
สถานการณ์สำหรับ Flexible: ภายใน Row มีสองปุ่ม ปุ่มแรก — “ซื้อ” (ข้อความสั้น) ปุ่มที่สอง — “เพิ่มในตะกร้า” (ข้อความยาว) ด้วย Expanded ปุ่มทั้งสองจะถูกยืดให้มีความกว้างเท่ากัน และข้อความสั้นจะมีระยะห่างมหาศาล ด้วย Flexible แต่ละปุ่มจะใช้ความกว้างของข้อความ และพื้นที่ว่างจะยังคงอยู่ระหว่างปุ่มหรือที่ขอบ
สถานการณ์สำหรับ Expanded: ภายใน Column มีการ์ดสามใบที่ต้องมีความสูงเท่ากันโดยไม่ขึ้นกับเนื้อหา Expanded แบ่งความสูงว่างอย่างเท่าเทียมกัน และการ์ดแต่ละใบจะถูกยืดให้มีขนาดเท่ากัน Flexible แบบ loose จะไม่ทำงานที่นี่ — การ์ดใบเล็กจะยังคงเล็ก ทำให้การออกแบบที่สม่ำเสมอเสียหาย
สรุป: เลือก Flexible เมื่อเนื้อหากำหนดขนาดขององค์ประกอบและพื้นที่ว่างรอบๆ ยอมรับได้ เลือก Expanded เมื่อองค์ประกอบทั้งหมดต้องมีขนาดเท่ากันโดยไม่ขึ้นกับเนื้อหา
ตัวอย่างที่ 1 สาธิตการใช้งานพื้นฐานของ Flexible กับ FlexFit.loose ใน Row
Row(
children: [
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.amber,
child: const Text('สั้น'),
),
),
Flexible(
fit: FlexFit.loose,
child: Container(
color: Colors.cyan,
child: const Text('ข้อความยาวสำหรับสาธิต'),
),
),
],
)
ในตัวอย่าง Flexible ทั้งสองใช้ loose fit คอนเทนเนอร์แรกที่มีข้อความสั้นใช้ความกว้างตามธรรมชาติ คอนเทนเนอร์ที่สองที่มีข้อความยาว — ความกว้างของตัวเอง Row จัดสรรให้แต่ละคอนเทนเนอร์ครึ่งหนึ่งของความกว้างว่าง แต่ loose fit อนุญาตให้คอนเทนเนอร์มีขนาดเล็กลง และพื้นที่ว่างยังคงว่างระหว่าง它们
ตัวอย่างที่ 2 — การเปรียบเทียบ Flexible กับ Tight และ Loose fit ใน Column
Column(
children: [
Flexible(
fit: FlexFit.tight,
child: const Card(
child: ListTile(
title: Text('Tight — ความสูงเต็มที่ยืดออก'),
),
),
),
const SizedBox(
height: 8,
),
Flexible(
fit: FlexFit.loose,
child: const Card(
child: ListTile(
title: Text('Loose — ความสูงตามธรรมชาติ'),
),
),
),
],
)
ใน Column Flexible แรก (tight) ยืดการ์ดให้มีความสูงครึ่งหนึ่งของพื้นที่ว่าง Flexible ที่สอง (loose) — การ์ดใช้ความสูงตามเนื้อหาและพื้นที่ที่เหลือว่างเปล่า มองเห็นได้ว่า tight เติมเต็มพื้นที่แบบบังคับ ในขณะที่ loose รักษาขนาดกะทัดรัด
สรุป: ในโค้ดการผลิต Flexible แบบ loose ใช้สำหรับฟิลด์ฟอร์ม ปุ่ม และบล็อกข้อความ Flexible แบบ tight เทียบเท่ากับ Expanded และใช้สำหรับการกระจายที่เท่าเทียมกัน
ข้อผิดพลาด 1: การใช้ Flexible นอกคอนเทนเนอร์ Flex เช่นเดียวกับ Expanded Flexible จะโยน LayoutException ถ้าไม่ได้อยู่ภายใน Row, Column หรือ Flex วิธีแก้ไข: ตรวจสอบห่วงโซ่วิดเจ็ตพ่อแม่เสมอ
ข้อผิดพลาด 2: การสับสนระหว่าง Flexible และ Expanded นักพัฒนามักใช้ Expanded เมื่อต้องการ Flexible แบบ loose fit และในทางกลับกัน ผลลัพธ์: Expanded ยืดองค์ประกอบที่มีข้อความสั้น สร้างระยะขอบว่างขนาดใหญ่ วิธีแก้ไข: ถ้าขนาดขององค์ประกอบสามารถเล็กกว่าที่จัดสรรได้ — ใช้ Flexible(fit: FlexFit.loose)
ข้อผิดพลาด 3: แฟกเตอร์ flex เป็นศูนย์ Flexible ที่ flex=0 ทำตัวเหมือนวิดเจ็ตที่ไม่ยืดหยุ่น ซึ่งอาจไม่เข้าใจได้โดยสัญชาตญาณ นักพัฒนาคาดหวังพฤติกรรมที่ยืดหยุ่น แต่องค์ประกอบใช้ขนาดต่ำสุด วิธีแก้ไข: flex ควรเป็น ≥1 สำหรับการกระจายพื้นที่ที่Active
ข้อผิดพลาด 4: Flexible ภายใน ScrollView โดยไม่มีข้อจำกัดด้านขนาด ถ้า Flexible อยู่ใน Column ภายใน SingleChildScrollView คอนเทนเนอร์เลื่อนให้พื้นที่ไม่จำกัด และการกระจาย flex ไม่ทำงาน วิธีแก้ไข: จำกัดขนาดของคอนเทนเนอร์เลื่อนโดยใช้ SizedBox หรือ ConstrainedBox
สรุป: Flexible ต้องการความใส่ใจต่อบริบทพ่อแม่เช่นเดียวกับ Expanded ข้อแตกต่างเพียงอย่างเดียวคือ fit — เลือกมันอย่างมีจุดประสงค์ตามงาน
คำถามที่พบบ่อย
Expanded คือ Flexible ที่มี fit=tight คงที่ ความแตกต่างคือ Expanded มีพันธะที่เข้มงวดในการเติมเต็มพื้นที่ว่างทั้งหมด ในขณะที่ Flexible สามารถใช้ loose fit เพื่อรักษาขนาดธรรมชาติของลูก
สำหรับปุ่มที่มีความยาวข้อความต่างกัน ใช้ Flexible(fit: FlexFit.loose) แต่ละปุ่มจะใช้ความกว้างของเนื้อหา และจะไม่มีความไม่สมดุลระหว่าง它们 Expanded จะทำให้ปุ่มทั้งหมดมีความกว้างเท่ากัน
ตั้งค่า fit: FlexFit.tight — Flexible จะบังคับให้ลูกเติมเต็มพื้นที่ที่จัดสรรทั้งหมด ในโหมดนี้ Flexible เหมือนกับ Expanded โดยสมบูรณ์ในพฤติกรรม
ได้ ถ้าลูกใหญ่กว่าพื้นที่ที่จัดสรร Flexible ส่งผ่านข้อจำกัดด้วยขนาดสูงสุดเท่ากับส่วนแบ่งของคอนเทนเนอร์ Flex ถ้าลูกเกินขนาดนี้ มันจะถูกหดภายในข้อจำกัด
ได้ Flexible ทำงานกับคอนเทนเนอร์ Flex ใดๆ รวมถึง Row, Column และวิดเจ็ตพื้นฐาน Flex ที่มีทิศทางตามต้องการ Flex อนุญาตให้ตั้งค่าทิศทางที่ไม่มาตรฐานผ่าน mainAxisAlignment และ crossAxisAlignment
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม