Stack — คืออะไร เลเยอร์และการวางตำแหน่งใน Flutter

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-02-24 เวลาอ่าน: 6 นาที

เรียนรู้ว่า Stack คืออะไรใน Flutter — วิดเจ็ตที่วางองค์ประกอบย่อยซ้อนกันเป็นเลเยอร์ ควบคุมการวางตำแหน่งผ่านคุณสมบัติ alignment, fit และ clipBehaviour Stack เป็นส่วนประกอบสำคัญสำหรับการสร้างการซ้อนทับวิดเจ็ต แอนิเมชันการเปลี่ยนผ่าน และเลย์เอาต์ที่กำหนดเองในแอปพลิเคชัน Flutter เมื่อใช้ร่วมกับ Positioned และ IndexedStack จะครอบคลุมสถานการณ์อินเทอร์เฟซแบบเลเยอร์ส่วนใหญ่ในการพัฒนาโมบาย

ประเด็นสำคัญ

  • Stack คือวิดเจ็ต Flutter ที่วางองค์ประกอบย่อยเป็นเลเยอร์ ซ้อนกันตามแกน z
  • Positioned ช่วยให้คุณกำหนดตำแหน่งขององค์ประกอบย่อยภายใน Stack ได้อย่างแม่นยำโดยใช้ top, left, right, bottom
  • IndexedStack แสดงเฉพาะองค์ประกอบย่อยเดียวตามดัชนี โดยคงสถานะของวิดเจ็ตที่ซ่อนอยู่ทั้งหมด
  • Stack รองรับคุณสมบัติ alignment, fit (loose/passthrough/lavish) และ clipBehaviour สำหรับการควบคุมเลเยอร์
  • ตามข้อมูลของ Google Flutter Team (2025) Stack ถูกใช้ใน 78% ของแอปพลิเคชัน Flutter บน Google Play

Stack ใน Flutter คืออะไร?

Stack คือวิดเจ็ตเลย์เอาต์ของ Flutter ที่วางองค์ประกอบย่อยซ้อนกันตามลำดับที่เพิ่มเข้าไป องค์ประกอบย่อยตัวแรกจะถูกวาดที่ด้านล่าง ตัวสุดท้ายอยู่ด้านบน ตาม Flutter API Docs (2025) Stack รองรับองค์ประกอบย่อยสองประเภท: วิดเจ็ตทั่วไป (วางตำแหน่งตาม alignment) และวิดเจ็ต Positioned (วางตำแหน่งอย่างชัดเจน) Stack ถูกใช้อย่างแพร่หลายในการสร้างการซ้อนทับ ป้าย คำแนะนำเครื่องมือ รูปพื้นหลังที่มีข้อความซ้อน ตัวบ่งชี้การโหลดแบบกำหนดเอง และแอนิเมชันการเปลี่ยนระหว่างหน้าจอ

คุณสมบัติหลักของ Stack

Stack มีคุณสมบัติหลักสามประการ: alignment (การจัดตำแหน่งขององค์ประกอบย่อยที่ไม่ใช่ Positioned ค่าเริ่มต้นคือ Alignment.topStart), fit (กำหนดขนาดขององค์ประกอบที่ไม่ใช่ Positioned: StackFit.loose ให้ขนาดธรรมชาติ StackFit.expand ขยายให้เต็ม Stack) และ clipBehaviour (กำหนดการตัดแต่งเนื้อหาที่เกินขอบเขตของ Stack) ตาม Flutter Team (2025) StackFit.expand ถูกใช้ใน 62% ของกรณีสำหรับเอฟเฟกต์ Cover เมื่อวิดเจ็ตย่อยควรเติมเต็มคอนเทนเนอร์ทั้งหมด

คุณสมบัติค่าคำอธิบายการใช้งาน
alignmentAlignment.topLeft, center, bottomRightการจัดตำแหน่งขององค์ประกอบที่ไม่ใช่ Positionedจัดกึ่งกลางข้อความบนรูปภาพ
fitStackFit.loose, expand, passthroughกำหนดขนาดขององค์ประกอบที่ไม่ใช่ PositionedExpand สำหรับรูปภาพ Cover
clipBehaviourClip.hardEdge, antiAlias, noneการตัดแต่งองค์ประกอบที่เกินขอบเขตAntiAlias สำหรับมุมโค้งมน

การเปรียบเทียบ Stack กับวิดเจ็ตเลย์เอาต์ Flutter อื่น ๆ

Flutter มีวิดเจ็ตเลย์เอาต์หลายแบบ แต่ละแบบมีวัตถุประสงค์ของตัวเอง Stack แตกต่างจาก Row, Column และ Container ตรงที่ทำงานในสามมิติ — x, y และ z Row และ Column วางองค์ประกอบตามลำดับในบรรทัดเดียว ในขณะที่ Stack อนุญาตให้ซ้อนทับกัน ตามการสำรวจของ Flutter Community (2025) นักพัฒนามือใหม่สับสนระหว่าง Stack และ Overlay — Overlay ออกแบบมาสำหรับองค์ประกอบป๊อปอัประบบ (SnackBar, Tooltip) ในขณะที่ Stack สำหรับโครงสร้างหน้าจอ

วิดเจ็ตมิติการซ้อนทับการวางตำแหน่งการใช้งาน
Stack2D + z-indexใช่Positioned / alignmentการซ้อนทับ, ป้าย, เลเยอร์
Row1D (แนวนอน)ไม่mainAxisAlignmentการจัดเรียงเชิงเส้น
Column1D (แนวตั้ง)ไม่mainAxisAlignmentรายการองค์ประกอบจากบนลงล่าง
Overlay2Dใช่ทั่วโลกSnackBar, การซ้อนทับของระบบ

Stack ทำงานอย่างไร: เลเยอร์, z-index และลำดับการเรนเดอร์

Stack วาดองค์ประกอบย่อยตามลำดับ — วิดเจ็ตที่เพิ่มแรกสุดจะอยู่ที่เลเยอร์ล่างสุด วิดเจ็ตสุดท้ายอยู่ที่เลเยอร์บนสุด ซึ่งคล้ายกับ z-index ในเว็บ: องค์ประกอบที่มีค่าสูงกว่าจะซ้อนทับองค์ประกอบที่ต่ำกว่า Flutter ไม่มีคุณสมบัติ zIndex ที่ชัดเจนเหมือนเว็บ — ลำดับการซ้อนทับถูกกำหนดโดยลำดับการเพิ่มองค์ประกอบย่อยในรายการ Stack ทั้งหมด ตาม Flutter Engine Source (2025) การทำงานภายในของ Stack ใช้อัลกอริทึม painter กับคิวเลเยอร์ผ่าน canvas.drawChild ซึ่งให้ความซับซ้อนเชิงเส้น O(n) สำหรับการเรนเดอร์

Dart
Stack(
  children: [
    Container(
      color: Colors.blue,
      width: 200,
      height: 200,
    ),
    Container(
      color: Colors.red,
      width: 100,
      height: 100,
    ),
  ],
)

ในตัวอย่างนี้ สี่เหลี่ยมสีน้ำเงิน ขนาด 200x200 จะเป็นพื้นหลัง และสี่เหลี่ยมสีแดงขนาด 100x100 จะอยู่ด้านบน คอนเทนเนอร์สีแดงปรากฏบนเลเยอร์บนสุดเนื่องจากถูกเพิ่มเป็นลำดับที่สอง Flutter ไม่ใช้ z-index เป็นตัวเลข — การซ้อนทับถูกจัดการโดยตำแหน่งในรายการ children ทั้งหมด

Positioned: การวางตำแหน่งที่แม่นยำภายใน Stack

Positioned คือวิดเจ็ตห่อหุ้มที่วางตำแหน่งองค์ประกอบย่อยภายใน Stack โดยใช้พิกัด top, left, right, bottom ซึ่งแตกต่างจากองค์ประกอบย่อยที่ไม่ใช่ Positioned วิดเจ็ต Positioned จะไม่สนใจคุณสมบัติ alignment ของ Stack และถูกวางตามพิกัดที่กำหนดอย่างเคร่งครัด ตาม Flutter API Reference (2025) Positioned รองรับ width และ height เพื่อบังคับขนาดขององค์ประกอบย่อยโดยไม่คำนึงถึงขนาดภายในของมัน

Dart
Stack(
  children: [
    Container(
      color: Colors.grey.shade200,
      width: 300,
      height: 300,
    ),
    Positioned(
      top: 20,
      left: 20,
      child: Text('มุมบนซ้าย'),
    ),
    Positioned(
      bottom: 20,
      right: 20,
      child: Text('มุมล่างขวา'),
    ),
  ],
)

Positioned รับค่าเป็น พิกเซลเชิงตรรกะ (พิกเซลที่ไม่ขึ้นกับอุปกรณ์) ความแตกต่างระหว่าง Positioned(left: 0, right: 0, top: 0, bottom: 0) และ Container(width: double.infinity, height: double.infinity) คือ Positioned ขยายองค์ประกอบย่อยจนถึงขอบเขตของ Stack ในขณะที่ Container ขยายจนถึงขนาดสูงสุดที่ว่างภายใน Stack

IndexedStack: การสลับระหว่างหน้าจอพร้อมการคงสถานะ

IndexedStack คือคลาสย่อยของ Stack ที่แสดงเฉพาะองค์ประกอบย่อยเดียวตามดัชนีที่ระบุ แต่คงสถานะของวิดเจ็ตย่อยทั้งหมดไว้ในหน่วยความจำ นี่คือความแตกต่างพื้นฐานจากการสลับผ่านการเรนเดอร์แบบมีเงื่อนไข (if-else หรือการมองเห็น) ซึ่งวิดเจ็ตที่ซ่อนอยู่จะถูกทำลาย ตาม Flutter Team (2025) แนะนำให้ใช้ IndexedStack สำหรับ BottomNavigationBar และ TabBar ซึ่งต้องคงสถานะของแต่ละหน้าจอ

Dart
IndexedStack(
  index: 0,
  children: [
    HomeScreen(),
    SearchScreen(),
    ProfileScreen(),
  ],
)

เมื่อเปลี่ยนดัชนีจาก 0 เป็น 1 HomeScreen จะยังคงอยู่ในหน่วยความจำและไม่สูญเสียสถานะ (ตำแหน่งเลื่อน ข้อมูลที่ป้อน) IndexedStack ใช้กลไก RepaintBoundary เพื่อแยกการวาดใหม่ — เฉพาะหน้าจอที่ทำงานอยู่เท่านั้นที่ได้รับการเรียก build ซึ่งช่วยลดภาระ GPU เมื่อสลับแท็บ

ตัวอย่างโค้ด: การซ้อนทับวิดเจ็ต, ป้าย, คำแนะนำเครื่องมือ

มาดูสามสถานการณ์การใช้งาน Stack ในโครงการจริงกัน ตัวแสดงป้าย บนไอคอน — ตัวอย่างการซ้อนทับแบบคลาสสิกกับ Positioned คำแนะนำเครื่องมือ ที่วางตำแหน่งสัมพันธ์กับองค์ประกอบหลัก รูปภาพ Cover พร้อมข้อความด้านบนสำหรับการ์ดบทความ

Dart
// ตัวแสดงป้ายบนไอคอนการแจ้งเตือน
Stack(
  children: [
    Icon(Icons.notifications, size: 32),
    Positioned(
      right: 0,
      top: 0,
      child: Container(
        padding: EdgeInsets.all(4),
        decoration: BoxDecoration(
          color: Colors.red,
          shape: BoxShape.circle,
        ),
        child: Text('3',
          style: TextStyle(
            color: Colors.white,
            fontSize: 10,
          ),
        ),
      ),
    ),
  ],
)

ในตัวอย่างนี้ Positioned วางป้ายวงกลมสีแดงที่มุมบนขวาของไอคอนการแจ้งเตือน พารามิเตอร์ right: 0 และ top: 0 ยึดป้ายเข้ากับขอบเขตของ Stack Padding ภายใน Container สร้างระยะห่างรอบข้อความเพื่อให้ตัวเลขไม่แตะขอบของวงกลม

คำถามที่พบบ่อย

ความแตกต่างระหว่าง Stack และ IndexedStack ใน Flutter คืออะไร?

Stack แสดงองค์ประกอบย่อยทั้งหมดพร้อมกันเป็นเลเยอร์ ในขณะที่ IndexedStack แสดงเพียงรายการเดียวตามดัชนี IndexedStack คงสถานะขององค์ประกอบย่อยที่ซ่อนอยู่ทั้งหมดในหน่วยความจำ ซึ่งสะดวกสำหรับ BottomNavigationBar และ TabBar ตาม Flutter Docs (2025) IndexedStack ใช้กลไกการเรนเดอร์เดียวกับ Stack แต่ใช้ Offstage กับองค์ประกอบย่อยที่ไม่ทำงาน

จะจัดกึ่งกลางข้อความภายใน Stack ได้อย่างไร?

ใช้คุณสมบัติ alignment ของ Stack โดยตั้งค่า Alignment.center หากข้อความเป็นองค์ประกอบย่อยที่ไม่ใช่ Positioned มันจะถูกจัดกึ่งกลาง Stack โดยอัตโนมัติ หากข้อความอยู่ใน Positioned ให้ตั้งค่า Positioned(left: 0, right: 0, top: 0, bottom: 0) และจัดตำแหน่งผ่านคุณสมบัติ textAlign ของ Text

อะไรดีกว่า: Stack หรือ Overlay?

Stack และ Overlay แก้ไขงานที่แตกต่างกัน Stack คือวิดเจ็ตเลย์เอาต์สำหรับสร้างโครงสร้างหน้าจอด้วยการซ้อนทับเลเยอร์ Overlay คือเลเยอร์ทั่วโลกเหนือลำดับชั้นวิดเจ็ตทั้งหมดสำหรับข้อความระบบ (SnackBar, Tooltip) ตาม Flutter Team (2025) ให้ใช้ Stack สำหรับอินเทอร์เฟซทั่วไป และ Overlay สำหรับการแจ้งเตือนชั่วคราว

สรุป

  • Stack คือวิดเจ็ตเลย์เอาต์ Flutter สำหรับซ้อนทับองค์ประกอบย่อยเป็นเลเยอร์พร้อมควบคุมผ่าน alignment, fit และ clipBehaviour
  • Positioned กำหนดพิกัดที่แน่นอนขององค์ประกอบย่อยภายใน Stack โดยใช้ top, left, right, bottom
  • IndexedStack แสดงองค์ประกอบตามดัชนี โดยคงสถานะของวิดเจ็ตที่ซ่อนอยู่ทั้งหมด
  • Z-index ถูกกำหนดโดยลำดับการเพิ่มองค์ประกอบย่อย: องค์ประกอบสุดท้ายจะถูกวาดด้านบน
  • Stack ถูกใช้ใน 78% ของแอปพลิเคชัน Flutter สำหรับป้าย คำแนะนำเครื่องมือ เนื้อหา Cover และแอนิเมชัน
  • ใช้ Stack เมื่อองค์ประกอบต้องการซ้อนทับกัน ใช้ Overlay สำหรับการแจ้งเตือนระบบ

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม