본문 바로가기

Flutter/Widget

[Widget] WillPopScope

휴대폰을 하다보면 Back Key or Button을 눌러서 이전 페이지로 넘어갈 때가 많은데, 

Flutter에서는 해당 Action을 WillPopScope를 사용해서 막는다.

 

아래 예제를 보며 살펴보자

 

// Scaffold를 WillPopScope로 감싸는 것

import 'package:flutter/material.dart';

void main() {
  runApp( MaterialApp(home: MyApp()) );
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {  
  String _msg = 'Welcome to WillPopScope World';

  @override
  initState() {
    super.initState();    
  }
  @override
  Widget build(BuildContext context) {
    return WillPopScope(    // <-  WillPopScope로 감싼다.
      onWillPop: () {
          setState(() {
            _msg = "You can not get out of here using back button";
          });
          return Future(() => false);
        },
      child: Scaffold(          
      appBar: AppBar(
          title: const Text('WillPopScopeTest'),
      ),
      body: Center(
          child: Text(_msg),
        ),
      ),
    );
  }
}

 

이 예제에서는 WillPopScope Class로 Scaffold를 감쌌다. 이렇게 해도 되고 body에 감싸주어도 된다.

 

  • onWillPop: 뒤로가기 하려고 할 때에 Action 작성할 수 있다. ( VoidCallback<bool> Type )

 

 

두번 눌렀을 때 뒤로가기가 가능한 경우가 있는데 그런 경우에는 다음과 같이 처리할 수 있다.

 

import 'package:flutter/material.dart';

class WillPopScopeDemo extends StatelessWidget {
  DateTime currentBackPressTime;

  final scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        bool result = onPressBackButton();
        return await Future.value(result);
      },
      child: Scaffold(
        key: scaffoldKey,
        appBar: AppBar(title: Text("WillPopScope Demo")),
        body: Center(
          child: Text("Tap back button to leave this page"),
        ),
      ),
    );
  }

  bool onPressBackButton() {
    DateTime now = DateTime.now();
    if (currentBackPressTime == null ||
        now.difference(currentBackPressTime) > Duration(seconds: 2)) {
      currentBackPressTime = now;
      scaffoldKey.currentState
        ..hideCurrentSnackBar()
        ..showSnackBar(SnackBar(
          content: Text("Tap back again to leave."),
        ));
      return false;
    }
    return true;
  }
}