แสดงข้อความด้านล่างหน้าจอด้วย SnackBar ใน flutter

เขียนเมื่อ 2 ปีก่อน โดย Ninenik Narkdee
flutter snackbar scaffoldmessenger

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ flutter snackbar scaffoldmessenger

ดูแล้ว 3,218 ครั้ง


 
SnackBar เป็น widget ที่เราสามารถใช้สำหรับแสดง popup ข้อความ
แบบย่อหรือการแจ้งเตือนถึงการกระทำบางอย่างๆ ที่เพิ่งเกิดขึ้น หรือเพื่อตัดสินใจ
จะแสดงขึ้นตรงขอบด้านล่างของหน้าจอแอพ ก่อนลงไปในรายละเอียด ต้องขอ
แจ้งก่อนว่า เราจะใช้เนื้อหาต่อเนื่องจากบทความตอนที่แล้ว
    การใช้งาน BottomNavigationBar ใน Flutter เบื้องต้น http://niik.in/961
 
    โดยจะใช้ในส่วนของหน้า home สำหรับทดสอบประกอบการทำงานและการใช้งาน
 
 

การใช้งาน SnackBar Widget

    รูปแบบการใช้งาน snackbar เช่น สมมติมีรายการที่แสดงบนหน้าจอ แล้วเราทำการ
เลือกรายการนั้นและลบออก เราอาจจะต้องการแจ้งว่าทำการลบรายการนั้นแล้ว หรืออาจจะ
แจ้งข้อความว่าลบรายการนั้นไปแล้วและมีปุ่มให้ทำคำสั่ง ยกเลิก การลบขึ้นมาพร้อมข้อความ
แจ้งก็ได้ เพื่อเป็นทางเลือกให้ผู้ใช้ตัดสินใจอีกครั้ง
    ในส่วนของ snackbar นอกจากจะแสดงเป็นข้อความแล้ว ยังสามารถใส่ widget อื่นๆ เพิ่ม
ลงไปได้ แต่ต้องคำนึงถึงพื้นที่การใช้งาน เพราะจะเป็นขอบเขตจำกัดเท่านั้น 
    เราจะทดสอบแสดงข้อความใน snackbar ด้วยรูปแบบอย่างง่ายดังนี้คือ เราจะสร้างปุ่มในหน้า
home แล้วเมื่อคลิกปุ่ม ก็ให้แสดง ข้อความใน snackbar
 
 
class _HomeState extends State<Home> {
 
    @override
    Widget build(BuildContext context) {
 
        return Scaffold(
            appBar: AppBar(
                title: Text('Home'),
            ),
            body: Center(
                child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                        Text('Home Screen'),
                        ElevatedButton(
                          onPressed: () { // เมื่อกดที่ปุ่ม
                            // กำหนดรูปแบบการใช้งาน snackbar
                            final snackBar = SnackBar(
                              content: const Text('Yay! A SnackBar!'), // แสดงข้อความ
                              action: SnackBarAction(
                                label: 'Undo',
                                onPressed: () {
                                  // ทำคำสั่งถ้ากดที่ข้อความใน action 
                                },
                              ),
                            );
                            // แสดงข้อความ snackbar โดยเรียกใช้งานผ่าน ScaffoldMessenger
                            ScaffoldMessenger.of(context).showSnackBar(snackBar);
                          },
                          child: const Text('Show SnackBar'),
                        ),
                    ],
                )
            ),
        );
    }
}
 

    ผลลัพธ์


 


 
 
    เราสร้างตัวแปรชื่อ snackBar เป็น final ขึ้นมาแล้วเรียกใช้งาน SnackBar widget กำหนดรูปแบบตาม
ต้องการ ในตัวอย่างกำหนดแค่ข้อความ และส่วนของ action เสมือนเป็นปุ่มข้อความ ให้ผู้ใช้เลือกที่จะกด
เพื่อทำคำสั่งเพิ่มเติม หลังจากนั้น ก็เรียกใช้งาน snackBar ผ่าน ScaffoldMessenger ซึ่งเป็นส่วนหนึ่งของ
Scaffold widget 
    จะเห็นว่ารูปแบบการใช้งาน ง่ายๆ ไม่ยุ่งยากซับซ้อน
    ลองมาปรับรูปแบบการแสดงส่วนของ snackbar เพิ่มเติม ดังนี้
 
// กำหนดรูปแบบการใช้งาน snackbar
final snackBar2 = SnackBar(
  content: Row( // แสดงข้อมูลอื่นๆ นอกจากข้อความอย่างเดียว
    children: [
      Icon(Icons.info_rounded,color: Colors.yellow,), // ใส่ไอคอน
      SizedBox(width: 10), // เพิ่มกล่องช่องว่าง
      Expanded(
        child: Text('ทำรายการเรียบร้อยแล้ว!'),
      ),
    ],
  ),
  action: SnackBarAction(
    label: 'ดูเพิ่มเติม',
    onPressed: () {
      // ทำคำสั่งถ้ากดที่ข้อความใน action 
    },
  ),
);
 

    ผลลัพธ์


 


 
 
    เนื่องจากว่าเรามีการใช้งาน BottomNavigationBar จึงเห็นว่าตัว SnackBar จะอยู่ด้านบนต่อขึ้นมาอีกที
 
    ดูตัวอย่างการกำหนดค่าเพิ่มเติม
 
// กำหนดรูปแบบการใช้งาน snackbar
final snackBar3 = SnackBar(
  content: Row( // แสดงข้อมูลอื่นๆ นอกจากข้อความอย่างเดียว
    children: [
      Icon(Icons.info_rounded,color: Colors.yellow,), // ใส่ไอคอน
      SizedBox(width: 10), // เพิ่มกล่องช่องว่าง
      Expanded(
        child: Text('ทำรายการเรียบร้อยแล้ว!'),
      ),
    ],
  ),
  duration: const Duration(milliseconds: 3000), // กำหนดเวลาแสดง 3 วินาที
  width: 300.0, // กำหนดความกว้่าง
  padding: const EdgeInsets.symmetric(
    horizontal: 8.0, 
  ),
  behavior: SnackBarBehavior.floating,
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.circular(10.0),
  ),  
  action: SnackBarAction(
    label: 'ดูเพิ่มเติม',
    onPressed: () {
      // ทำคำสั่งถ้ากดที่ข้อความใน action 
    },
  ),
);
 

    ผลลัพธ์


 


 
 
    ดูการกำหนดคุณสมบัติอื่นๆ เพิ่มเติมได้ที่ SnackBar Widget 
 
 
    เราสามารถแยกออกมาเป็นฟังก์ชั่นเพื่อให้เรียกใช้งานได้สะดวก และรองรับการส่งค่าตามต้องการ
ดูตัวอย่างตามโค้ดด้านล่าง
 
class _HomeState extends State<Home> {
 
    // สร้าง ScaffoldMessengerState key ให้สามารถเรียกใช้งาน ใน widget ที่กำหนดได้
    final GlobalKey<ScaffoldMessengerState> scaffoldMessengerKey =
        GlobalKey<ScaffoldMessengerState>();

    @override
    Widget build(BuildContext context) {
        return ScaffoldMessenger(
          key: scaffoldMessengerKey, // อ้างอิงค่า key ที่กำหนด
          child: Scaffold(
                appBar: AppBar(
                    title: Text('Home'),
                ),
                body: Center(
                    child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: <Widget>[
                            Text('Home Screen'),
                            ElevatedButton(
                              onPressed: (){
                                showSnack('Hi'); // เรียกใช้งานฟังก์ชั่น
                              },
                              child: const Text('Show SnackBar'),
                            ),
                        ],
                    )
                ),
          ),
        );
    }

    // ฟังกชั่นสำหรับใช้งาน SnackBar
    void showSnack(String title) {
     // กำหนดรูปแบบการใช้งาน snackbar
      final snackBar = SnackBar(
        content: Row( // แสดงข้อมูลอื่นๆ นอกจากข้อความอย่างเดียว
          children: [
            Icon(Icons.info_rounded,color: Colors.yellow,), // ใส่ไอคอน
            SizedBox(width: 10), // เพิ่มกล่องช่องว่าง
            Expanded(
              child: Text(title), // รับค่าข้อความจาก parameter มาแสดง
            ),
          ],
        ),
        duration: const Duration(milliseconds: 3000), // กำหนดเวลาแสดง 3 วินาที
        width: 300.0, // กำหนดความกว้่าง
        padding: const EdgeInsets.symmetric(
          horizontal: 8.0, 
        ),
        behavior: SnackBarBehavior.floating,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(10.0),
        ),  
        action: SnackBarAction(
          label: 'ดูเพิ่มเติม',
          onPressed: () {
            // ทำคำสั่งถ้ากดที่ข้อความใน action 
          },
        ),
      );
     scaffoldMessengerKey.currentState!.showSnackBar(snackBar);
    }

}
 

    ผลลัพธ์


 


 
 
    เราสามารถกำหนดไห้ SnackBar แสดงจนกว่ากดที่ปุ่มข้อความใน action โดยกำหนดรูปแบบ
ของเวลาใน duration เป็นดังนี้
 
duration: const Duration(days: 365), 
// duration: const Duration(milliseconds: 1500), // กำหนดเวลาแสดง 1.5 วินาที
// duration: const Duration(seconds: 3), // กำหนดเวลาแสดง 3 วินาที
 
    ปกติถ้าไม่กำหนด หรือกำหนดเป็นหน่วยมิลลิวินาที ตัว SnackBar ก็จะแสดงชั่วขณะ หรือตามที่กำหนด
เท่านั้น แต่หากเรากำหนดเป็นค่า days: 365 ก็เหมือนเป็นการบอกว่า เปิดค้างไว้ตลอด จนกว่าจะกดที่ปุ่มข้อ
ความใน action ตัว SnackBar ถึงจะหายไป  การกำหนดในลักษณะนี้ก็เพื่อเป็นการยืนยันว่าผู้ใช้ได้เห็นข้อความ
นี้และทำการใดๆ ต่อไปตามที่กำหนด หรือเป็นการให้ผู้ใช้โต้ตอบกับ SnackBar นั่นเอง แทนที่จะหายไปอัตโนมัติ
 
    การแสดง SnackBar จะแสดงตามลำดับการเรียกใช้งาน สมมติเรากดซ้ำที่ปุ่มเรียกใช้งาน 3 ครั้ง ตัว SnackBar
ก็จะแสดง ซ้ำ 3 ครั้งแต่ละครั้งก็จะใช้เวลา 3 วินาที ตามที่กำหนด 
 
    เราสามารถกำหนดให้ ทุกการเรียกใช้งาน SnackBar สามารถแสดงต่อเนื่องทันที โดยไม่ต้องรอจนครบตาม
เวลาที่กำหนด โดยใช้คำสั่ง removeCurrentSnackBar() ก่อนแล้วค่อยเรียกใช้คำสั่ง showSnackBar()
 
    ตัวอย่างการใช้งานกับ ScaffoldMessenger ก็จะเป็นประมาณนี้
 
ScaffoldMessenger.of(context)
..removeCurrentSnackBar() // ปิดตัวที่แสดงอยู่ก่อนทันที
..showSnackBar(snackBar);   // แล้วค่อยแสดงตัวใหม่  
 
    หรือกรณีใช้กับในฟังก์ชั่น ตัวอย่างด้านบน ก็จะเป็น
 
scaffoldMessengerKey.currentState!
..removeCurrentSnackBar()
..showSnackBar(snackBar);
 
    เราสามารถใช้คำสั่ง hideCurrentSnackBar() แทนได้ แต่จะให้ความรู้สึกเหมือนมี animation มากกว่า
กรณีใช้เป็น removeCurrentSnackBar()
 
 
    ดูการกำหนดคุณสมบัติอื่นๆ เพิ่มเติมได้ที่ SnackBar Widget 


กด Like หรือ Share เป็นกำลังใจ ให้มีบทความใหม่ๆ เรื่อยๆ น่ะครับ



อ่านต่อที่บทความ









เนื้อหาที่เกี่ยวข้อง









URL สำหรับอ้างอิง





คำแนะนำ และการใช้งาน

สมาชิก กรุณา ล็อกอินเข้าระบบ เพื่อตั้งคำถามใหม่ หรือ ตอบคำถาม สมาชิกใหม่ สมัครสมาชิกได้ที่ สมัครสมาชิก


  • ถาม-ตอบ กรุณา ล็อกอินเข้าระบบ
  • เปลี่ยน


    ( หรือ เข้าใช้งานผ่าน Social Login )







เว็บไซต์ของเราให้บริการเนื้อหาบทความสำหรับนักพัฒนา โดยพึ่งพารายได้เล็กน้อยจากการแสดงโฆษณา โปรดสนับสนุนเว็บไซต์ของเราด้วยการปิดการใช้งานตัวปิดกั้นโฆษณา (Disable Ads Blocker) ขอบคุณครับ