Never give up

Flutter - update previous screen with Navigator callback 본문

Flutter

Flutter - update previous screen with Navigator callback

대기만성 개발자 2021. 1. 5. 15:46
반응형

화면 A, B가 있고, A에서 B화면으로 Navigator push를 했다고 가정을 하고

 

B화면에서 어떤 조건을 충족시키고 Navigator pop을 하면

 

A화면에서 업데이트 하고싶을 때가 있습니다

 

Provider나 bloc 등 statemanagement를 통해 하는 방법도 있지만

 

해당 예제에서는 Navigator의 callback을 이용해 보겠습니다

 

메인

  String _value = 'N/A';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Callback example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            RaisedButton(
                child: Text('Go to next screen'),
                onPressed: () async {
                  bool isBack = await Navigator.push(context,
                      MaterialPageRoute(builder: (context) => TestPage()));
                  if (isBack) {
                    _update();
                  }
                }),
            Text(_value)
          ],
        ),
      ),
    );
  }

  void _update() {
    setState(() {
      _value = 'Test is finished';
    });
  }

test page

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () => _onBackPressed(context),
      child: Scaffold(
          appBar: AppBar(title: Text('Test page')),
          body: Center(
              child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              RaisedButton(
                  child: Text('Update text'),
                  onPressed: () => Navigator.pop(context, true)),
              Text('Test page. You can go back with update'),
            ],
          ))),
    );
  }

  Future<bool> _onBackPressed(BuildContext context) async {
    Navigator.pop(context, false);
    return true;
  }

 

먼저 push를 할 때 async await을 이용해서 pop 될때까지 기다려줍니다

 

그리고 pop이 될때 가져오는 result값을 받아서 bool값 isBack에 저장해주고

 

bool값을 통해 update메소드를 콜하거나 하지않는 간단한 예제입니다

 

여기서 주의점은 pop할 때 result값에 다른 데이터타입을 할당하거나

 

아예값을 주지않으면 에러가 발생하고 만약 pop이 아닌 pushandremove같은것을 사용하면

 

callback이 실행되지 않으니 이 부분만 주의하면 될거 같습니다

 

다른 방법으로는 then을 사용하는 방법인데

Navigator.push(context,
    MaterialPageRoute(builder: (context) => TestPage()))
    .then((value) {
        if (value) {
            _update();
        }
    });

따로 비동기 처리를 안해줘도 돼서 더 간단하고 좋을거 같습니다

 

그리고 pop과 함께 가져오는 값 result을 이용해서 업데이트 하려면

 

다음과 같이 하면 됩니다

 

여기서 사용할 데이터 타입은 String입니다

void _update(String value) {
    setState(() {
      _value = value;
    });
  }

먼저 업데이트 부분에 값을 받을 수 있도록 해주고

Navigator.push(context,
    MaterialPageRoute(builder: (context) => TestPage()))
    .then((value) {
        _update(value);
    });

업데이트에 값을 전달합니다

 

그리고 pop 동작에서

Navigator.pop(context, 'This is true');

다음과 같이 String 값을 전달하면 pop 동작과 함께

 

result값 = then의 value값을 가지고 옵니다

 

간단한 예제인데 상황에 따라서는 유용하게 사용할 수 있을거 같습니다

 

ex) AlertDialog, snackbar, stream, setstate 등등

반응형
Comments