한국의 개발자들을 위한 Google for Developers 국문 블로그입니다.
Flutter에서 WebView의 파워를 느껴보세요!
2019년 5월 29일 수요일
<블로그 원문은
이곳
에서 확인하실 수 있습니다>
휴대기기의 브라우저를 열 필요 없이 웹페이지를 표시할 수 있는 앱을 작성하고 싶으세요? 또는 웹사이트에 구현된 안전한 결제 흐름을 이미 마련해두었으므로 모바일 앱에 결제 기능을 다시 구현하고 싶지 않을 수도 있을 것입니다. 돈 문제는 소홀히 할 수 없는 사항으로, 실수로 Save the
Kraken
Fund로 지불 금액의 절반을 보낸다거나 하는 일이 없기를 바라실 겁니다. 아, 저한테만 해당하는 얘기 아니냐고요? 어쨌든, Flutter 팀은 Flutter 앱에 WebView를 통합하여 이 모든 기능을 사용 가능하도록 만들어주는
정말 멋진 플러그인
을 만들었습니다.
크라켄을 회복시키자는 게 아니라, 필자는 단지 Flutter 앱에 웹사이트를 표시하는 기능을 말한 것입니다.
다른 위젯과 똑같은 Flutter WebView
WebView 플러그인을 앱에 통합하는 방법은 극히 간단합니다. 이 플러그인은 다른 위젯과 다를 것 없는 위젯일 뿐입니다. WebView(initialUrl: ‘https://flutter.io'). WebView에서 javascriptMode 매개변수로 자바스크립트를 선택적으로 사용하거나 중지할 수도 있습니다. WebView에서는 기본적으로 자바스크립트가 비활성화되어 있으므로, 이를 활성화하여 사용하려면 WebView를 다음과 같이 작성하세요.
WebView(
initialUrl: 'https://flutter.io',
javascriptMode: JavascriptMode.unrestricted,
)
WebView에 대해 알고 싶은 거의 모든 정보와 WebView를 제어하는 기능도 바로 WebViewController를 통해 사용할 수 있습니다. 이 컨트롤러는 WebView가 완전히 빌드되어 있을 때 콜백에서 반환됩니다.
WebViewController _controller;
WebView(
initialUrl: 'https://flutter.io',
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
},
);
//...later on, probably in response to some event:
_controller.loadUrl('http://dartlang.org/');
WebViewController는 Flutter에서 WebView를 프로그래밍 방식으로 수정하거나 현재 표시되고 있는 URL과 같은 속성에 액세스하기 위한 티켓입니다. 이 모든 것의 실제 작동 방식을 살펴보기 위해, 필자는 다음에 찾아보기 쉽게 페이지를 북마크할 수 있는 간단한 Wikipedia 검색 앱을 작성했습니다.
위키 래빗홀
이라는 말이 있습니다. Wikipedia에서 우연히 발견한 유용한 자료를 다음에 찾으려 할 때 도저히 그 탐색 경로를 알 수 없는 상황을 일컫는데, 그 경로를 절대 잊지 않도록 해주는 게 바로 이 앱입니다.
WebView를 사용하여 Flutter로 작성한 Wikipedia 탐색 앱. 나중에 볼 수 있도록 페이지를 즐겨찾기에 저장할 수 있습니다.
이 위키 래빗홀 브라우저의 완전한 코드는
GitHub 저장소
에서 찾아보실 수 있습니다.
WebView는 Flutter로 만든 다른 위젯과 똑같으며 그 위의 계층에 다른 위젯을 작성하는 식으로 구성할 수 있습니다. 즐겨찾기 버튼은 WebView 위로 마우스를 가져가면 나타나는 일반적인 FloatingActionButton일 뿐이며, 이런 버튼에서 흔히 볼 수 있는 음영 효과를 주어 완성할 수 있습니다. 또한 앱 바에서 드롭다운 메뉴가 열리면 메뉴 아래에 있는 다른 위젯과 마찬가지로 메뉴가 WebView를 부분적으로 가리게 됩니다.
코드를 살펴보면 필자가 이 샘플에서 Completer 클래스와 FutureBuilder를 자주 사용한다는 점을 알아차릴 수 있을 것입니다. _controller 인스턴스 변수를 Completer로 선언하는 것은 WebViewController의 자리표시자를 설정하는 것과 같습니다. _controller.isCompleted(즉, 유효한 WebViewController가 있을 때 완료됨)를 호출하거나
FutureBuilder를 _controller.future와 함께 사용
하여 WebViewController가 올바로 작동하는지 검사할 수 있습니다. 올바로 작동하는 WebViewController가 있어야만 FutureBuilder를 사용하여 즐겨찾기 추가를 위한 FloatingActionButton과 같은 새로운 UI 컴포넌트를 빌드할 수 있습니다. 그렇지 않으면 프로그램이 즐겨찾기 페이지를 저장할 때
currentUrl
을 가져올 방법이 없을 것이기 때문입니다.
WebView에 관한 다른 두 가지 특징은 조금 복잡할 수 있으므로, 이어지는 두 섹션에서 좀 더 자세히 살펴봅시다.
특정 동작도 포착할 수 있는 WebView
WebView는 Flutter 위젯이므로 Flutter의 동작 명확화 프로토콜(
일명 Gesture Arena
)에 참가할 수 있습니다. WebView는 기본적으로 어떤 동작을 클레임한 다른 위젯이 하나도 없는 경우에만 그 동작에 대해 응답합니다. 하지만 WebView가 gestureRecognizers를 지정하여 어떤 동작을 선제적으로 클레임하도록 만들 수 있습니다.
WebView가 동작에 응답하는 다른 위젯(예: ListView) 내부에 있는 경우 앱이 동작에 응답하는 방식을 지정하고 싶을 수도 있을 것입니다. 사용자가 화면을 가로질러 손가락을 드래그할 경우 ListView나 WebView 중 어느 것을 스크롤하도록 만들어야 할까요? 두 위젯 모두 스크롤 가능하도록 하려는 경우, WebView 위젯은 사용자가 WebView를 드래그할 때 스크롤하지만 그렇지 않을 때는 ListView를 스크롤하도록 드래그 동작을 '포착'할 수 있습니다. gestureRecognizers 매개변수를 사용하여 WebView 위젯으로 전달할 동작을 지정할 수 있습니다. 이 매개변수는 포착하려는 모든 GestureRecognizers로 구성된 Set를 받습니다. Factory 객체에 괜히 겁먹지 마세요. 기본적으로 이 객체는 단지 미화된 빌더 메서드일 뿐입니다. 세로 방향의 스크롤 이벤트를 포착하려면 다음과 같이 작성할 수 있습니다.
WebView(
initialUrl: someUrl,
gestureRecognizers: Set()
..add(Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer())),
)
또는 다음과 같이 다른 방식으로 작성할 수도 있습니다.
var verticalGestures = Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer());
var gestureSet = Set.from([verticalGestures]);
return WebView(
initialUrl: someUrl,
gestureRecognizers: gestureSet,
);
Boring Flutter Development Show
를 시청하시는 분 중에 우리가 Kraken News를 개발하는 모습을 보신 분이 계실지 모르겠습니다. 즉,
Hacker
News Reader 앱 말입니다.
YouTube 쇼에서 개발해온 Hacker News 앱의 최신 버전
앱의 컨텍스트에서 동작 포착을 보여드리기 위해, 필자는 웹페이지 중 일부를 '미리보기'로 보여주도록 Hacker News 앱을 수정했습니다. 이를 통해 사용자는 연결된 페이지를 세로 방향으로 스크롤하면서 더 자세히 읽어보기 위해 별도의 페이지를 열 것인지 결정할 수 있습니다.
링크의 WebView 미리보기 기능이 있는 Hacker News Reader 앱. WebView는 세로 방향의 드래그 동작을 포착하여 미리보기를 스크롤할 수 있도록 합니다.
이 Hacker News Reader 앱의 코드는
이 GitHub 저장소
에서 찾으실 수 있습니다. (아마 여기서는 _buildItem에 대한 코드를 보여줄 것임)
하지만 관심을 두지 않는 동작을 포착할 뿐인 위젯 내부에 WebView가 있는 경우에는 아무런 동작 감지기도 필요하지 않습니다. 예를 들어 PageController는 가로 방향의 드래그 동작에만 응답하고 WebView는 세로 방향으로 스크롤할 수만 있도록 하고 싶다면, 코드를 다음과 같이 작성할 수 있을 것입니다.
PageView(children: [
WebView(initialUrl: urlOne),
WebView(initialUrl: urlTwo),
WebView(initialUrl: urlThree),
]));
PageView의 WebView. PageView는 가로 방향의 스와이프 동작을 제어하므로 개발자가 따로 아무런 작업을 하지 않아도 WebView는 세로 방향으로 스크롤할 수 있습니다.
키 매개변수가 필요할 수도 있는 WebView
Flutter 코드베이스의 모든 위젯 생성자에서 어디서나 선택적으로 사용되는 키 매개변수를 보신 적이 있을 것입니다. 앱에서 제거되거나 추가되거나 다시 정렬되는 같은 유형의 여러 상태 저장 위젯이 있는 경우에 키가 필요합니다. 아시다시피, WebView는 상태 저장 위젯입니다(현재 페이지와 브라우저 방문 기록을 포함한 상태). 따라서 앱에 WebView가 여러 개 있으면 키 매개변수를 추가해야 할 수도 있습니다.
이런 상황의 예가 실제로 Hacker News 앱에 있습니다! 다음은 탭을 전환하는데 WebView에 키가 없을 경우 어떻게 되는지 보여줍니다.
상태 저장 앱에서 키를 사용하지 않을 경우 일어나는 일을 보여줍니다. 'New Stories' 탭으로 변경할 때 잘못된 웹 미리보기 페이지가 표시됩니다.
여기서 알 수 있듯이, 탭을 전환할 때 'Interview with Alan Kay' 타일이 확장되지만 WebView는 여전히 Virgin Galactic에 관한 BBC 페이지를 보여줍니다! 이 페이지는
맨 위에 있는
컬렉션 위젯(이 경우에는 ExpansionTile)에 키를 배치하여 고정된 것입니다.
휴! 키를 사용해 Reader 앱의 각 항목에 대해 다른 WebView와 그에 상응하는 올바른 웹사이트를 표시하는 방법으로 문제가 해결됩니다.
어째서 키로 이 문제가 풀리는지에 관해 아주 간략하게 설명하자면, Flutter는 표시할 스토리 목록을 전환할 때 각 스토리 세트가 ExpansionTile 항목을 포함한 ListView로 만들어지는 것으로 보기 때문이라는 것입니다. Flutter는 위젯 유형과 키를 검사하는 화면을 불필요하게 다시 그리지 않도록 하기 위한 빠른 비교 알고리즘을 가지고 있습니다. 키가 없으면 각 목록의 위젯 유형이 동일하므로 상태 비추적 항목(예: 링크 제목)은 전부 업데이트되지만, 상태 저장 컴포넌트(예: ExpansionTile과 웹사이트 URL의 확장된 상태)는 다시 그려지지 못합니다. 키를 추가하면 이 문제가 해결됩니다. 더 자세한 설명은 키에 관한 다음 동영상을 참조하세요.
마찬가지로,
Hero
위젯의 컨텍스트에서 WebView를 사용하는 경우 두 WebView가 실제로는 같은 것이라는 사실을 Flutter가 알고서는 두 번째 WebView를 다시 렌더링하지 않도록 전역 키를 사용하고 싶으실 것입니다.
명심하셔야 할 나머지 몇 가지 사항:
WebView 플러그인은 현재 Developer Preview 단계에 있으며, 그동안 우리가 완성도를 높이기 위한 추가 작업을 마칠 것입니다. 즉, iOS에서 WebView 플러그인을 실행하고 싶으면 ios/Runner/Info.plist에서 <dict> 내부에 다음 행도 추가해야 한다는 뜻입니다.
<key>io.flutter.embedded_views_preview</key><string>yes</string>
(
이 GitHub 문제에 설명되어 있음
)
현재로서는 Android 키보드와 관련되어 알려진 문제도 있는데, Flutter 팀에서
수정 작업 중
입니다.
Flutter 팀의 위 플러그인이 지닌 기능을 전부 가지고 있지는 않지만, 또 다른 커뮤니티 기반 WebView 플러그인이 있습니다. 이 플러그인은 기본 뷰에 웹페이지를 간단히 표시하며 Flutter 위젯 트리의 나머지 부분과 통합되지 않습니다. 따라서 그 버전을 사용하여 임의의 다른 Flutter 위젯으로 WebView를 작성할 수는 없습니다. 이 글에서 설명한
webview_flutter plugin
을 사용하면 이 문제를 피할 수 있습니다.
이것으로 오늘 글은 마치겠습니다! 이제 개발자 여러분의 Flutter 앱에 WebView를 추가해 보세요. 그래서 크라켄에게도 사랑을 나눠주세요.
Contents
ML/Tensorflow
Android
Flutter
Web/Chrome
Cloud
Google Play
Community
Game
Firebase
검색
Tag
인디게임페스티벌
정책 세미나
창구프로그램
AdMob
AI
Android
Android 12
Android 12L
Android 13
Android 14
Android Assistant
Android Auto
Android Games
Android Jetpack
Android Machine Learning
Android Privacy
Android Studio
Android TV
Android Wear
App Bundle
bootcamp
Business
Chrome
Cloud
Community
compose
Firebase
Flutter
Foldables
Game
gdg
GDSC
google
Google Developer Student Clubs
Google Play
Google Play Games
Interview
Jetpack
Jetpack Compose
kotlin
Large Screens
Library
ma
Material Design
Material You
ML/Tensorflow
mobile games
Now in Android
PC
Play Console
Policy
priva
wa
wear
Wearables
Web
Web/Chrome
Weeklyupdates
WorkManager
Archive
2024
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2023
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2022
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2021
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2020
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2019
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2018
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2017
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2016
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2015
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2014
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2013
12월
11월
10월
9월
8월
7월
6월
5월
4월
3월
2월
1월
2012
12월
11월
10월
9월
8월
7월
6월
5월
3월
2월
1월
2011
12월
11월
Feed