개발아빠/Flutter

플러터(Flutter) WebView 사용 및 History 제어 기능 추가

육아개발아빠 2020. 10. 7. 14:22

안녕하세요.

육아개발아빠입니다. 

오늘도 개발아빠의 플러터 이야기는 계속 됩니다. 

 

오늘은 WebView에 대해서 이야기 해보겠습니다.

안드로이드, 아이폰 어플리케이션 개발때 익숙하게 사용하는 것이 WebView입니다. 하이브리드앱도 있듯이요~

플러터에서도 당연히 웹뷰를 이용할일이 있겠죠~ 

 

먼저 WebView를 추가해보겠습니다~

 

WebView는 플러터 기본적인 위젯에는 없고, 추가해야합니다.

pubspec.yamldependencies:

webview_flutter: ^0.3.24 추가합니다. 버전은 현재 플러터 버전에 따라서 조금씩 다를수 있습니다. 

자세한 내용은 여기에서 확인하세요. https://pub.dev/packages/webview_flutter

dependencies:
  flutter:
    sdk: flutter

  webview_flutter: ^0.3.24

그리고 아래와 같이 위젯을 만들어봅니다.

class WebViewPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('웹뷰 걸음마'),
      ),
      body: Container(
        child: WebView(
          initialUrl: "https://m.naver.com",
          javascriptMode: JavascriptMode.unrestricted,
        ),
      )
    );
  }
}

initialUrl 은 최초 로딩되는 url이고,

javascriptMode는 자바스크립트를 사용할지 인데, 기본은 disabled인데, 웬만한 웹뷰에 자바스크립트를 켜주는게 맞지 않나싶으니,

JavascriptMode.unrestricted 로 넣어준다,

 

WebView가 잘 뜨는군요~ 아이폰도 확인해보니 잘 나옵니다~ (저 믿죠^^)

 

그런데 안드로이드에서 BackKey를 누르니, 그냥 화면이 내려가버리네요~

WebView에 history가 있을 경우에는 이전 화면으로 가야하는데 그렇게 되고 있지 않아요~ 

 

그래서 버튼을 BackKey가 없는 아이폰을 생각해서 버튼을 FloatingActionButton을 올려서 History Back이 가능하게 만들어볼게요~

 

먼저 WebView 컨트롤러를 붙여볼께요~ 

 

final Completer<WebViewController> _controller = Completer<WebViewController>();

 

이렇게 선언해주시고 

WebView에

onWebViewCreated: (WebViewController webViewController) {
	_controller.complete(webViewController);
},

 

코드를 추가해줍니다. 

 

그리고 Scaffold에 floatingActionButton 을 추가해줍니다. 

floatingActionButton: FutureBuilder<WebViewController>(
          future: _controller.future,
          builder: (BuildContext context,
              AsyncSnapshot<WebViewController> controller) {
            if (controller.hasData) {
              return FloatingActionButton(
                  child: Icon(Icons.arrow_back),
                  onPressed: () {
                    controller.data.goBack();
                  });
            }

            return Container();
          }
      ),

그냥 제가 막 혼자서 추가해버리니까 이게 뭔지 하시겠지만, 뭐 일단 너무 자세히는 이야기 안하고 

몇가지 키워드만 볼께요~

 

Dart에 Completer라는 것은 Callback을 Future로 변환해 주는 클래스입니다. 

그러면 Future가 뭐길래 변환을 해주는 걸까요? 

Future는 Javascript에서 Promise라고 생각하시면 됩니다. Promise는 또 뭐죠? 

음. 일단 비동기라는 키워드만 기억하고 갑시다~

FutureBuilder는 Future가 들어오면 반응을 하는 아이라고 보시면 됩니다. 

 

코드의 내용을 말로 좀 풀어보면,

WebView가 변하는 상태를 Controller에 담아두고 있다가, 

FloatingActionButton을 눌러서 컨트롤러 통해 History Back을 실행하는거죠~

 

풀코드로 보시면

class WebViewPage extends StatelessWidget {

  final Completer<WebViewController> _controller = Completer<WebViewController>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('웹뷰 걸음마'),
      ),
      body: Container(
        child: WebView(
          initialUrl: "https://m.naver.com",
          javascriptMode: JavascriptMode.unrestricted,
          onWebViewCreated: (WebViewController webViewController) {
            _controller.complete(webViewController);
          },
        ),
      ),
      floatingActionButton: FutureBuilder<WebViewController>(
          future: _controller.future,
          builder: (BuildContext context,
              AsyncSnapshot<WebViewController> controller) {
            if (controller.hasData) {
              return FloatingActionButton(
                  child: Icon(Icons.arrow_back),
                  onPressed: () {
                    controller.data.goBack();
                  });
            }

            return Container();
          }
      ),
    );
  }
}

 

버튼이 누르는건 안보이지만 암튼 뒤로 가기가 잘 되네요~

아이폰도 잘됩니다 (저를 믿어주세요)

 

자 이제 안드로이드, 아이폰은 웹뷰가 해결 되었습니다.

이제 플러터의 더 날개를 달기위해 같은 코드로 웹도 올려볼께요~

 

flutter run -d chrome

 

 

으악... 공포의 빨간 화면이 떴네요...

 

플러터 너란녀석은 왜 웹은 이렇게 잘 안되는거니....

아닙니다. 반드시 방법을 찾을껍니다~

 

오늘의 이 방법은 일단 네이티브로 개발하시는분들에게 유용하실꺼같고,

이제 웹까지 지원을 고려하시는 분들은 다음 포스팅에서 다른 대안을 가지고 찾아오겠습니다.

 

오늘도 즐코하세요~