MakerHyeon

[Flutter] 스낵바(Snack bar)와 BuildContext 본문

Flutter

[Flutter] 스낵바(Snack bar)와 BuildContext

유쾌한고등어 2023. 4. 6. 21:06

<코드 실행 결과화면>


build(BuildContext context)...에서 사용되는 BuildContext는 return되는 위젯의 것이 아니라, 이함수를 불러오는 BuildContext가 context가 된다! 여기에서는 MyPage의 context를 뜻한다.

scaffold.of(context) 메소드가 의미하는 바는 현재 buildContext에서 위로 거슬러 올라가며 가장 가까운 Scaffold 위젯을 찾아 반환하라는 것이다. 하지만 이를 찾지못해 문제가 생기고,이를 해결하기 위해 builder위젯을 추가해주는것이다.

플러터 2.0에는 여기저기 흩어져있는 SnackBar를 관리하는 ScaffoldMessenger라는 새로운 위젯이 추가되었다!

 

+) 한 페이지에서만 스낵바가 보여지고 페이지 이동을 하면 스낵바가 즉시 사라지게 하려면...?
=> 루트 scaffoldMessenger가 아니라, 개별적 scaffoldMessenger를 생성해야 한다.

 

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false, // 디버그 없애기
      title: 'Snack Bar',
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      home: const MyPage(), // 앱실행시 가장먼저 보여지는 경로
    );
  }
}

class MyPage extends StatelessWidget {
  const MyPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Scaffold Messenger'),
        centerTitle: true,
      ),
      body: const HomeBody(),
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.thumb_up),
        onPressed: () {
          // ScaffoldMessenger는 가장 가까운 ScaffoldMessenger를 찾아서 반환
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: const Text('Like a new Snack bar!'),
              duration: const Duration(seconds: 5),
              action: SnackBarAction(
                label: 'Undo',
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: ((context) => const ThirdPage())),
                  );
                },
              ),
            ),
          );
        },
      ),
    );
  }
}

// home page
class HomeBody extends StatelessWidget {
  const HomeBody({super.key});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: ElevatedButton(
        child: const Text('Go to the second page'),
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => const SecondPage()),
          );
        },
      ),
    );
  }
}

// second page
class SecondPage extends StatelessWidget {
  const SecondPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Page'),
      ),
      body: const Center(
        child: Text(
          '"좋아요가 추가 되었습니다',
          style: TextStyle(
            fontSize: 20.0,
            color: Colors.redAccent,
          ),
        ),
      ),
    );
  }
}

/**
 * 한 페이지에서만 스낵바가 보여지고 페이지 이동을 하면 스낵바가 즉시 사라지게 하려면...?
=> 루트 scaffoldMessenger가 아니라, 개별적 scaffoldMessenger생성해야함
 */

// Third Page
class ThirdPage extends StatelessWidget {
  const ThirdPage({super.key});

  @override
  Widget build(BuildContext context) {
    return ScaffoldMessenger(
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Third Page'),
        ),
        body: Builder(
          // builder위젯은 반드시 위젯을 리턴해주어야 함
          builder: (context) {
            return Center(
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  const Text(
                    '"좋아요"를 취소 하시겠습니까?',
                    style: TextStyle(fontSize: 20.0, color: Colors.redAccent),
                  ),
                  ElevatedButton(
                      onPressed: () {
                        ScaffoldMessenger.of(context).showSnackBar(
                          const SnackBar(
                            content: Text('"좋아요" 가 취소되었습니다.'),
                            duration: Duration(seconds: 3),
                          ),
                        );
                      },
                      child: const Text('취소하기'))
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}

/*

class ThirdPage extends StatelessWidget {
  const ThirdPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Third Page'),
        ),
        body:  Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children:   [
            const Text('"좋아요"를 취소 하시겠습니까?',
             style: TextStyle(fontSize:20.0, color: Colors.redAccent),
             ),
             ElevatedButton(onPressed: (){
              ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                content: Text('"좋아요" 가 취소되었습니다.'),
                duration: Duration(seconds:3),
              ),);

             }, child: const Text('취소하기'))
            ],
          ),
        ),
        );
  }
}
*/
Comments