✅ 이번 시간에는 플러터 2.0으로 인해서 SnackBar의 사용이 완전히 달라짐.
정리가 다음 포스팅까지 이어짐.
1. ScaffoldMessenger class
2. Buttons(TextButton, ElevatedButton, OutlinedButton)
3. Global Key
✅ Why ScaffoldMessger?
우선 Scaffold.of(context)를 살펴보자
기본적으로 Scaffold.of(context)의 경우에는 위로 올라가면서 가장 가까운 Scaffold를 찾아 반환하라는 의미.
하지만, 이 과정에서 Scaffold.of 메소드가 가지고 있는 현재의 컨텍스트로는 Scaffold를 찾을 수 없었다.
이 문제를 해결하기 위해서 Builder위젯을 생성해서 새로운 context를 Scffold.of 메소드가 전달받게 한 후 그 위치에서 부터 위젯 트리 상에 Builder 위에 위치하고 있는 Scaffold 위젯을 찾아나서는 방식으로 이 문제를 해결했었다.
아래의 그림은 문제해결 방식에 대한 위의 글에 대한 설명이다.
그럼 기존의 스낵바는 어떤 문제를 가졌을까?
바로 현재 context는 현재의 위치를 참조하고 있기에 화면을 바꾸게 되면 새로운 context가 생겨서 기존 SnackBar가 context를 찾지 못해 오류가 발생한다.
그럼 이 문제를 해결하려면 어떻게 해야할까???
ScaffoldMessenger를 최상단에 두고 각각의 SnackBar에서 자손 Scaffold들을 참조하게 한다.
✅ 코드리뷰 및 코드의 이해
import 'package:flutter/material.dart'; // 데스크탑, 앱 등에 고루 UI를 적용할 수 있게 해주는 구글이 제공해주는 패키
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
// 실질적으로 모든 앱을 감싸고 있다.
title: 'Appbar', // 앱을 총칭하는 이름 -> 스마트 폰 앱에서 최근 사용한 앱 보여줄 때의 이름
theme: ThemeData(primarySwatch: Colors.red // 특정색의 응용들을 기본 색상으로 지정해서 사용하겠
),
home: MyPage(), // home은 앱이 실행될 때 가장먼저 보여주는 페이
);
}
}
class MyPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Snack Bar'),
),
body: HomeBody(), // 바디 부분에 홈 바디를 둔다.
floatingActionButton: FloatingActionButton( // 플로팅 버튼도 배치
child: Icon(Icons.thumb_up),
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar( // 스캐폴드메신저 만들기
// 가장 가까운 스캐폴드 찾아서 반환해
SnackBar( // 스낵바
content: Text('Like a new Snack Bar!'), // 내
duration: Duration(seconds: 5),
action: SnackBarAction( // 스낵바 액션 - 우측에 달리는 아이템 버튼!
label: 'Undo',
onPressed: () {
Navigator.push(context, // 네비게이션 형식으로 push형식으로 전환
MaterialPageRoute(builder: (context) => ThirdPage())); // 화면전환 코드
},
),
),
);
},
),
);
}
}
class HomeBody extends StatelessWidget {
const HomeBody({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center( // 센터임!! 주
child: ElevatedButton( // 엘레베이티드 버튼
child: Text('Go to the second page'),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => SecondPage())); // 두번쨰 페이지로 전환
},
),
);
}
}
class SecondPage extends StatelessWidget {
const SecondPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Second Page'),
),
body: Center(
child: Text(
'"좋아요가 추가되었습니다."',
style: TextStyle(fontSize: 20.0, color: Colors.redAccent),
),
),
);
}
}
class ThirdPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScaffoldMessenger(
child: Scaffold(
appBar: AppBar(
title: Text('Third Page'),
),
body: Builder( // 빌더를 통해서 context를 받아야 해.
builder: (context){
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'"좋아요를 취소하시겠습니까?"',
style: TextStyle(fontSize: 20.0, color: Colors.redAccent),
),
ElevatedButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(SnackBar( // 스캐폴드 메신저가 스낵바 들고 있음!!
// 이렇게 하면 화면을 빠져나가서 context가 사라지면 스낵바가 사라져서 UI개선
content: Text("좋아요가 취소되었습니다"),
duration: Duration(seconds: 3),
));
},
child: Text('취소하기'),
),
],
),
);}
),
),
);
}
}
주의깊게 봐야할 점에 대해서만 간단히 짚고 넘어가자.
✅ body 부분에 HomeBody를 두어 따로 구현했다는 점.
내가 플러터를 배우면서 위젯이라 간편하다는 생각은 드는데 코드가 많아지고 길어질수록 유지보수가 너무 힘들 거 같다는 생각이 들었는데 분리할 수 있어서 그나마 다행.. 디자인 패턴에 대해서 끊임없이 공부해야겠다!
✅ 다음은 버튼들인데, 이건 뭐 그냥 보다보면 눈에 익으니까!!
✅ ThirdPage쪽에서 return ScaffoldMessenger로 감싼 후에 child로 Scaffold를 사용했고, 거기에 builder를 붙인 후에 builder 파라미터를 통해서 context를 주어서 구현했다라는 점이다.
이것이 왜 대단하냐면, ScaffoldMessenger가 호출되고 난 후에 3초 동안 지속해야 하는데 유저라 backButton을 통해서 화면을 나가버리면? 그러면 기존에는 SnackBar가 남아있는 문제가 있는데 이렇게 구현하면 화면을 나가는 즉시 스낵바가 사라진다.
왜 그럴까? builder로 준 context를 참조하여 화면이 나가면 builder가 사라져서 Scaffold를 놔주게 되므로 사라지게 된다.
쉽게 비교해볼 수 있는것이 첫 페이지에서는 좋아요를 누르고 가운데 엘리베이티드 버튼을 누르면 스낵바가 남아있는데, 확실히 차이를 느낄 수 있다.
아래 사진을 보자.
✅ Second Page로 이동해도 스낵바 남아있음
✅ ThirdPage를 보자. 스낵바 즉시 사라짐
어떤 차이가 있는지 알겠는가?
그럼에도 불구하고 논리적으로 완벽히 이해했음을 한번 더 정리해보자
'flutter > 순한맛(기초)' 카테고리의 다른 글
[flutter] 19강 | 빌더 위젯 없이 스낵바 만들기 및 토스트 메시지 (0) | 2021.08.13 |
---|---|
[flutter] 27강(패치강좌) | 플러터 2.0 버튼 (0) | 2021.08.13 |
[flutter] 17강 | BuildContext 이해하기 (0) | 2021.08.11 |
[flutter] 16강 | Drawer 메뉴 만들기 2 (0) | 2021.08.11 |
[flutter] 15강 | Drawer 메뉴 만들기 1 (0) | 2021.08.10 |