본문 바로가기

Flutter

[Flutter Favorite] WebView화면에서 플러터 화면으로 돌아오기 구현

반응형

문제발생!  

앱 내에서 외부 링크를 웹뷰로 발생시키고 웹 뷰에서 뒤로가기 버튼을 클릭하면 플러터 앱으로 다시 돌아와야 합니다. 

url_launcher를 사용하면 간단하게 화면을 띄울 수는 있지만 기기 화면에 뒤로가기 버튼이 존재하는 안드로이드 기기와 달리 아이폰에서는 유저가 다시 앱으로 돌아오기가 조금 곤란해보입니다. 

 

문제를 해결하기 위해서는 url_launcher보다는 web_view를 사용해야 하는 순간으로 판단됩니다.? 그럼 구현해보겠습니다. 

 

// pubspec.yaml 추가
	webview_flutter: ^3.0.4

 

공식문서에 따르면 웹뷰를 사용하기 위해 android app 내 build.gradle 파일의 minsdk version을 20으로 맞춰주면 된다고 합니다. 

 android {
     defaultConfig {
         minSdkVersion 20
     }
 }

 

그리고 화면을 띄워봅니다. 성공!

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

class WebViewScreen extends StatefulWidget {
  WebViewScreen({Key? key}) : super(key: key);

  @override
  State<WebViewScreen> createState() => _WebViewScreenState();
}

class _WebViewScreenState extends State<WebViewScreen> {
  @override
  void initState() {
    super.initState();
    if (Platform.isAndroid) WebView.platform = AndroidWebView();
  }

  @override
  Widget build(BuildContext context) {
    return WebView(
      initialUrl: 'https://flutter.dev',
    );
  }
}

 

뒤로가기 버튼을 추가해줍니다.  필요하지 않은 코드는 모두 주석으로 지워뒀습니다. 주석 없는 부분만 보세욥

class NavigationControls extends StatelessWidget {
  const NavigationControls(this._webViewControllerFuture, {Key? key})
      : assert(_webViewControllerFuture != null),
        super(key: key);

  final Future<WebViewController> _webViewControllerFuture;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<WebViewController>(
      future: _webViewControllerFuture,
      builder:
          (BuildContext context, AsyncSnapshot<WebViewController> snapshot) {
        final bool webViewReady =
            snapshot.connectionState == ConnectionState.done;
        final WebViewController? controller = snapshot.data;
        return Row(
          children: <Widget>[
            IconButton(
              icon: const Icon(Icons.arrow_back_ios),
              onPressed: !webViewReady
                  ? null
                  : () async {
                      if (await controller!.canGoBack()) {
                        await controller.goBack();
                      } else {
                        ScaffoldMessenger.of(context).showSnackBar(
                          const SnackBar(content: Text('No back history item')),
                        );
                        return;
                      }
                    },
            ),
            // IconButton(
            //   icon: const Icon(Icons.arrow_forward_ios),
            //   onPressed: !webViewReady
            //       ? null
            //       : () async {
            //           if (await controller!.canGoForward()) {
            //             await controller.goForward();
            //           } else {
            //             ScaffoldMessenger.of(context).showSnackBar(
            //               const SnackBar(
            //                   content: Text('No forward history item')),
            //             );
            //             return;
            //           }
            //         },
            // ),
            // IconButton(
            //   icon: const Icon(Icons.replay),
            //   onPressed: !webViewReady
            //       ? null
            //       : () {
            //           controller!.reload();
            //         },
            // ),
          ],
        );
      },
    );
  }
}

 

반응형