공부방/Flutter

Flutter web 에서 Flutter app event call

soycrab 2023. 7. 4. 14:31

Flutter web으로 만든 웹 페이지를

Flutter App webview에 띄우고 웹 페이지에서 버튼을 눌렀을 때 

네이티브 App에 특정 이벤트를 발생 시키려고 하는데 생각보다 잘 되지 않네요..... 

여기저기 자료를 찾아보다가 살짝 방식이 다르다는걸 깨닫고 

혹시 삽질 하는 사람이 있을까 봐 글을 남겨 놓아요 ㅎㅎ

 

먼저 Flutter web 프로젝트의 

web 폴더에 script.js 파일을 생성해요. (이름은 뭐로 하든 상관없어요.)

 

script.js

function showAlert() {
     channelName.postMessage("Hello from JS");
}

channelName 부분은 Flutter App에서 JavascriptChannel name 부분에 들어갈 이름을 적어주시면 돼요! 

 

index.html

<head>
  <script src="script.js" defer></script>
</head>

index.html 파일을 열어서 head 부분에 코드를 넣어주세요. 

위에서 만든 script.js 파일명과 일치해야 해요. 

 

main.dart 

callMothod() {
  js.context.callMethod("showAlert", []); 
}

실제 사용할 때에는 위 방식으로 호출하면 돼요.

 

 

마지막으로 

 

Flutter App 프로젝트에서 위에서 작성한 웹페이지에서 이벤트 값을 받아올 거예요. 

 

 

web_view.dart

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:go_router_flow/go_router_flow.dart';
import 'package:webview_flutter/webview_flutter.dart';
import '../../app/core/ui/ui.dart';

class WebViewApp extends StatefulWidget {
  
  final String? url;
  final String? title;

  const WebViewApp({Key? key, required this.url, this.title}) : super(key: key);

  @override
  State<WebViewApp> createState() => _WebViewAppState();
}

class _WebViewAppState extends State<WebViewApp> {

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: AppColor.white,
      body: WebView(
        onWebViewCreated: (WebViewController webViewController) {
          _completerController.future.then((value) => _controller = value);
          _completerController.complete(webViewController);
        },
        backgroundColor: AppColor.white,
        initialUrl: widget.url ?? '',
        javascriptMode: JavascriptMode.unrestricted,
        javascriptChannels: Set.from([
          JavascriptChannel(
              name: 'channelName',
              onMessageReceived: (JavascriptMessage message) {
                print("message.message ${message.message}");
              })
        ]),
      ));
  }

  Future<void> goBack(BuildContext context) async{
    final canGoBack = await _controller?.canGoBack();
    if(canGoBack == true){
      _controller?.goBack();
    }else{
      if(mounted) GoRouter.of(context).pop();
    }
  }
}

 

 

반응형