Using FractionallySizedBox in Combination with Wrap

Using FractionallySizedBox in Combination with Wrap

One approach to achieve flex like css

Flutter มีวิดเจ็ตมากมายสำหรับการสร้าง UI ที่ถูกออกแบบมาเพื่อตอบโจทย์แบบจำเพาะของทุกการออกแบบ UI หนึ่งในการออกแบบที่ท้าทายใน Flutter, ซึ่งสามารถทำได้อย่างง่ายดายบนเว็บไซต์ด้วย Bootstrap, คือการจัดการกับการแบ่งคอลัมน์ในลักษณะที่ทำให้คอลัมน์สุดท้ายสามารถขึ้นบรรทัดใหม่ได้เอง หากมีการเพิ่มเข้ามา ตัวอย่างเช่น:

<div class="row">
    <div class="col-3"></div>
    <div class="col-3"></div>
    <div class="col-3"></div>
    <div class="col-3"></div>
    <div class="col-3"></div> <!-- This will automatically move to a new line -->
</div>

ในตัวอย่างด้านบน, แต่ละ div มีความกว้าง 25% ของพื้นที่ของมัน, และ div ตัวสุดท้ายจะถูกย้ายไปยังบรรทัดใหม่โดยอัตโนมัติ แต่เมื่อพยายามทำสิ่งเดียวกันใน Flutter, วิดเจ็ตแรกที่เรานึกถึงคือ Row ซึ่งสามารถใส่ Flex หรือ Expanded วิดเจ็ตได้ อย่างไรก็ตาม, ทั้งหมดจะยังคงอยู่ในบรรทัดเดียวกันโดยไม่ขึ้นบรรทัดใหม่:

Row(
    children: [
        Expanded(),
        Expanded(),
        Expanded(),
        Expanded(),
        Expanded(),
    ],
),

เพื่อทำให้ได้ผลลัพธ์ที่คล้ายคลึงกับตัวอย่างใน Bootstrap, เราสามารถใช้วิดเจ็ต Wrap ร่วมกับ FractionallySizedBox ใน Flutter

วิดเจ็ต Wrap ทำงานคล้ายกับ Row แต่มีความสามารถพิเศษในการย้ายวิดเจ็ตลูกที่มีขนาดเกินไปยังบรรทัดใหม่ นี่เป็นการทำงานที่เหมาะสำหรับการออกแบบที่มีความยืดหยุ่นและมีโอกาสที่จะไม่ครบแถวอย่างพอดี และ FractionallySizedBox จะสามารถกำหนดขนาดของวิดเจ็ตในรูปแบบสัดส่วน (fraction) ตามขนาดของวิดเจ็ตแม่ไว้ได้:

Wrap(
    children: [
        FractionallySizedBox(widthFactor: 0.25),
        FractionallySizedBox(widthFactor: 0.25),
        FractionallySizedBox(widthFactor: 0.25),
        FractionallySizedBox(widthFactor: 0.25),
        FractionallySizedBox(widthFactor: 0.25),
    ],
),

จากโค้ดทั้งหมดด้านบนจะเป็นโค้ดอย่างง่ายเพื่อให้เข้าใจ concept เท่านั้น ถ้าเอาไปรันจริงๆจะเห็นเป็นแค่เส้นๆอย่างเดียว ผมได้ทำโค้ดตัวอย่างเพื่อสาธิตการใช้งาน Wrap และ FractionallySizedBox วิดเจ็ตไว้ด้านล่างเพื่อให้ไปลองเล่นกันได้เหมือนเดิม หวังว่าจะมีประโยชน์กับผู้อ่านทุกคนนะครับ

โค้ดตัวอย่าง