포스트

Flutter Overlayed Snackbar

플러터에서 스낵바를 띄울 때 그냥

1
2
3
4
5
6
7
ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(text, style: const TextStyle(color: Colors.white)),
        backgroundColor: Colors.black,
        duration: Duration(seconds: duration),
      ),
    );

이렇게 하면 됩니다. 밀리초 단위로 띄우려면 이렇게 하면 되죠.

1
2
3
4
5
6
7
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(text, style: const TextStyle(color: Colors.white)),
        backgroundColor: Colors.black,
        duration: Duration(milliseconds: duration),
      ),
    );

그래서 지난 번에 이런 위젯을 만들어 사용했었습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Open Snackbar with text and duration
void _showSnackbar(BuildContext context, String text, int duration,
    {bool isMillis = false}) {
  if (isMillis == false) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(text, style: const TextStyle(color: Colors.white)),
        backgroundColor: Colors.black,
        duration: Duration(seconds: duration),
      ),
    );
  } else {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(text, style: const TextStyle(color: Colors.white)),
        backgroundColor: Colors.black,
        duration: Duration(milliseconds: duration),
      ),
    );
  }
}

그런데 이 위젯의 단점은,

dialog 뒤에서 띄워진다는 점입니다.

그래서 dialog 를 오버레이(덮는) 스낵바가 필요할 수 있습니다.

스낵바 처럼 보여지는 메시지창을 화면 가장 앞에 띄우는 위젯을 만들었습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// Open Snackbar with text and duration on top of all other widgets
void _showOverlaySnackbar(BuildContext context, String text, int duration, {bool isMillis = false}) {
  OverlayState overlayState = Overlay.of(context)!;
  OverlayEntry overlayEntry = OverlayEntry(
    builder: (context) => Positioned(
      bottom: 0.0, // Distance from the bottom of the screen
      left: 0.0,
      right: 0.0,
      child: Material(
        elevation: 10.0,
        child: Container(
          padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
          decoration: BoxDecoration(
            color: Colors.black,
            borderRadius: BorderRadius.circular(0.0),
          ),
          child: Text(
            text,
            style: const TextStyle(color: Colors.white),
          ),
        ),
      ),
    ),
  );

  overlayState.insert(overlayEntry);

  // Wait for duration and then remove the overlay entry
  Future.delayed(
    isMillis ? Duration(milliseconds: duration) : Duration(seconds: duration),
    overlayEntry.remove,
  );
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.