ค้นหาบล็อกนี้

วันพฤหัสบดีที่ 28 มกราคม พ.ศ. 2564

[Flutter] การจัดการ Layout ของ Flutter ด้วย Column และ Row

Layout 

โดยวันนี้ ผมจะมาพูดถึงการจัดการ Widget ของ Flutter ด้วย Widget ที่ใช้สำหรับจัดการ Widget หลายๆตัวโดยทั้วไปแล้วนั้นจะมีด้วยกันหลาย Widget ตัวอย่างเช่น

  • Column
  • Row
  • ListView

 แต่สำหรับบทความนี้ผมจะพูดถึงแค่ 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 กำลังพัฒนาอยู่นะครับ หวังว่า จะมีประโยชน์กับผู้ที่สนใจนะครับ