Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
WebView+ViewGroupを実現するAOSPメールアプリの内部実装とニュースアプリ...
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
ogapants
February 07, 2019
Technology
3.9k
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
WebView+ViewGroupを実現するAOSPメールアプリの内部実装とニュースアプリへの応用 / DroidKaigi2019
https://droidkaigi.jp/2019/timetable/70923
ogapants
February 07, 2019
More Decks by ogapants
See All by ogapants
5分でわかるWebView+ViewGroupを実現するAOSPメールアプリの内部実装と ニュースアプリへの応用 / Otemachi.apk02
ogapants
0
770
ScrollViewで 読了計測した話
ogapants
0
870
「AndroidはiOSと同じデザインで!」と言われたときのTips
ogapants
17
8.5k
たのしいAndroidかいはつ
ogapants
0
180
Fabric Digitsで始めるSMS認証
ogapants
1
1.3k
MediaController をカスタマイズするぞ
ogapants
0
2.8k
Other Decks in Technology
See All in Technology
データレイクの「見えない問題」を可視化する
sansantech
PRO
1
200
AI時代のコスト管理を考えよう〜明日から使える実践AWSノウハウ~
yoshimi0227
0
860
AIをフル活用してオンコール機能のプロトタイプを2日で作った話 / Building an AI-Powered On-Call Prototype in Just Two Days
nari_ex
0
120
2026-06-24_人とAIの責務分離に基づく開発プロセスの提案.pdf
takahiromatsui
0
120
感情と身体を置き去りにしない、エンジニアの生きのこり方 ──いまから、ここから「自分の状態」を扱うという選択
saorimurooka
0
330
AIチャットの改善から見えた、良いAI体験とは / What Constitutes a Good AI Experience: Insights from Improving AI Chat
kubode
0
120
Comment regagner la souveraineté de vos données tout en étant payé grâce à Nostr !
rlifchitz
0
190
作る力から、見極める力へ — AI時代に広がるエンジニアの価値と役割
rince
0
330
40代で“やっとエンジニアになれた”――閉じた学びを開き、空の青さを知る / 20260628 Naoki Takahashi
shift_evolve
PRO
4
830
GitHub Copilot 最新アップデート – 「一歩先」の実践活用術
moulongzhang
5
1.7k
10年間のブログ発信を振り返って見えたWebアプリケーションエンジニアとしての軌跡
stefafafan
0
180
コミュニティの有益性 ~JAWS Days 2026 での体験を通して~ / The Benefits of a Community ~Through My Experience at JAWS Days 2026~
seike460
PRO
0
270
Featured
See All Featured
WCS-LA-2024
lcolladotor
0
650
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
The Cult of Friendly URLs
andyhume
79
6.9k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.5k
Bash Introduction
62gerente
615
220k
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
The Pragmatic Product Professional
lauravandoore
37
7.3k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
240
Code Reviewing Like a Champion
maltzj
528
40k
Prompt Engineering for Job Search
mfonobong
0
350
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.1k
Six Lessons from altMBA
skipperchong
29
4.3k
Transcript
WebView+ViewGroupΛ࣮ݱ ͢ΔAOSPϝʔϧΞϓϦͷ෦ ࣮ͱχϡʔεΞϓϦͷԠ༻ 2019/02/08 DroidKaigi @ogapants
ࣗݾհ • ͓͕ͺΜ@ogapants • ຊܦࡁ৽ฉࣾ • ٕज़ॻయͰνʔϜվળͱAndroidStudioͷ Tipsʹ͍ͭͯॻ͖·ͨ͠ɻnoteͰݟΕ·͢ʂ https://goo.gl/AWv7v1
WebView+ViewGroupΛ࣮ݱ ͢ΔAOSPϝʔϧΞϓϦͷ෦ ࣮ͱχϡʔεΞϓϦͷԠ༻
͍͖ͳΓͰ͕͢ • ͜͏͍͏ߏͷը໘ɺͲ͏ͬͯ εΫϩʔϧͤ͞·͔͢ʁ TextView WebView Image View Text View
TextView
͍͖ͳΓͰ͕͢ • ScrollViewͰ ғͬͪΌ͍·ͤΜ͔ʁ TextView WebView Image View Text View
TextView ScrollView?
• ScrollViewͰWebViewΛғ͍͚ͬͯ·ͤΜ • ғ͏ͱͲ͏ͳΔͷʁ • ͡Ό͋Ͳ͏͢Ε͍͍ͷʁ
͜ͷൃදͰ͢͜ͱ • ͳͥScrollViewͰWebViewΛғ͏ͷ͕Α͘ͳ͍͔ • AOSPϝʔϧͰWebViewͲ͏ΘΕ͍ͯΔͷ͔ • Ͳ͏Ԡ༻ͨ͠ͷ͔
AOSPϝʔϧΞϓϦͱ
AOSPͱ • Android Open Source Project • ࣗ༝ʹӾཡɺ࠶ར༻͕Մೳ • OSपลͷใɺ։ൃπʔϧɺαϯϓϧΞϓϦͳͲఏڙ
• ϒϥβిɺΪϟϥϦʔΞϓϦͳͲ
AOSPϝʔϧΞϓϦͱ
AOSPϝʔϧΞϓϦͱ • AOSPʹ্͕ͬͯΔϝʔϧΞϓϦ • 2014͝Ζ·ͰҰ෦ͰϓϦΠϯετʔϧ • ࠓճϝʔϧৄࡉը໘ͷ • ·ͩΞοϓσʔτ͞Ε͍ͯΔ
AOSPϝʔϧΞϓϦϦϙδτϦ • ΞΧϯτपΓ https://android.googlesource.com/platform/packages/ apps/Email/ • ϝΠϯػೳ https://android.googlesource.com/platform/packages/ apps/UnifiedEmail/
AOSPϝʔϧΞϓϦϦϙδτϦ • ͲͪΒEclipseͷϑΝΠϧߏ • Γͳ͍ίϯϙʔωϯτଟ
ඇެࣜAOSPϝʔϧΞϓϦ • https://github.com/jinkg/YalinEmail • ඞཁͳίϯϙʔωϯτ܈ΛαϒϞδϡʔϧԽ͍ͯ͠Δ • AndroidStudioͰϏϧυͰ͖ΔΑ͏ʹͨ͠ඇެࣜΞϓϦ
[ิ]jinkg/YalinEmail modules • app... https://android.googlesource.com/platform/packages/apps/ Email/ • android-bitmap... https://android.googlesource.com/platform/ frameworks/opt/bitmap/
• android-chips... https://android.googlesource.com/platform/ frameworks/opt/chips/ • android-common... https://android.googlesource.com/platform/ frameworks/ex/+/master/common/
[ิ]jinkg/YalinEmail modules • android-emailcommon... https://android.googlesource.com/ platform/packages/apps/Email/+/master/emailcommon/ • android-photoviewer... https://android.googlesource.com/ platform/frameworks/opt/photoviewer/
• android-unifiedemail... https://android.googlesource.com/ platform/packages/apps/UnifiedEmail/
෦࣮Λ͏ܦҢ
͜Ε·Ͱͷݸผهࣄը໘ͷߏ TextView WebView Image View Text View TextView ScrollView ϔομʔViewGroupɿهࣄͷλΠτϧͳͲ
ίϯςϯπWebViewɿهࣄ༰ ϑολʔViewGroupɿؔ࿈هࣄͳͲ
࣮ࡍʹى͖ͨ
࣮ࡍʹى͖ͨᶃ • Ұ෦ͰසͰ هࣄ͕Εͯදࣔ͞ΕΔ • (WebViewͷΞοϓσʔτ ʹΑͬͯఆղܾ)
࣮ࡍʹى͖ͨᶄ • Ұ෦ͰසͰIllegalStateException >Unable to create layer for WebView •
(Ұ෦ͷϋʔυΣΞΞΫηϥϨʔγϣϯOFF Ͱఆղܾ)
࣮ࡍʹى͖ͨ • ͍ͣΕఆରԠͰ͔͠ͳ͍… • ߃ٱରԠ͘͢GoogleͷΤϯδχΞʹ࣭
࣮ࡍʹى͖ͨ • ScrollViewWebViewΛೖΕΔ͜ͱΛఆͯ͠ ࡞͍ͬͯͳ͍ʂ by GoogleΤϯδχΞ
ߟ͑ͨղܾࡦ
ߟ͑ͨղܾࡦ • WebViewΛΊΔ ˠશͯωΠςΟϒʹ͢Δɹ ˠ Өڹൣғ͕େ͖͘ࠔ
ߟ͑ͨղܾࡦ • WebViewͷΈʹ͢Δɹ ˠViewGroup෦ͷHTMLԽ ˠ ը໘ͷঢ়ଶ͕ଟ͘ࠔ
ߟ͑ͨղܾࡦ • AppBarLayoutͷΈΛར༻͢Δ ˠNestedScrollͰಈ͔͢ ˠ ٕज़తʹࠔ
ߟ͑ͨղܾࡦ • ϝʔϧΞϓϦΛࢀߟʹ͢Δ ˠ WebViewΛ͍ͬͯΔͣ ˠ AOSPΛݟΕ͍͚ͦ͏ʁ ˠ deep dive
ͪͳΈʹ • https://developer.android.com/reference/android/widget/ ScrollView • >Never add a RecyclerView or
ListView to a scroll view. • WebViewʹ͍ͭͯͷهࡌແ͠…
WebView+ViewGroupΛ ࣮ݱ͢ΔAOSPϝʔϧΞϓϦͷ ෦࣮
AOSPϝʔϧΞϓϦͰͷߏ • ֬ೝͨ͠όʔδϣϯ https://android.googlesource.com/platform/ packages/apps/UnifiedEmail/ ͷϦϏδϣϯ `1668ada` •
Ϗϧυڥjinkg/YalinEmail
AOSPϝʔϧΞϓϦͰͷߏ ϔομʔViewGroup ίϯςϯπWebView ϑολʔViewGroup
AOSPϝʔϧΞϓϦͰͷߏ WebView in ScrollView AOSPϝʔϧΞϓϦ WebView ViewGroup ScrollView ViewGroup WebView
ViewGroup ViewGroup
AOSPϝʔϧΞϓϦͰͷߏ • WebViewͰεΫϩʔϧͤ͞Δ • ViewGroup࿈ಈ • ViewGroupͷߴ͞cssͰpadding WebView ViewGroup ViewGroup
padding padding
ϝʔϧඳը·ͰͷྲྀΕ ᶃWebViewʹΦʔόʔϨΠ͍ͤͨ͞ViewGroupΛmeasure()ͯ͠ߴ͞ΛଌΔ ᶄςϯϓϨʔτͷhtmlʹcssͰpaddingΛ͚ͭΔ ᶅςϯϓϨʔτͷhtmlʹϝʔϧͷhtmlจࣈྻΛૠೖ ᶆ߹ͨ͠htmlจࣈྻΛWebViewͰඳը͢Δ ᶇpadding্ʹϔομʔɾϑολʔViewGroupΛlayout()Ͱஔ͢Δ
ϝʔϧඳը·ͰͷྲྀΕᶃ ᶃWebViewʹΦʔόʔϨΠ͍ͤͨ͞ViewGroupΛ ɹmeasure()ͯ͠ߴ͞ΛଌΔ ɹˠmeasure()…ViewͷαΠζΛܭଌ͢Δ ɹˠgetMeasuredHeight()Ͱऔಘ
ᶄςϯϓϨʔτͷhtmlʹcssͰpaddingΛ͚ͭΔ ϝʔϧඳը·ͰͷྲྀΕᶄ template_conversation_upper.html <div … style="height: %spx;”></div> ↓ ViewGroupͷߴ͞ <div
… style="height: 288px;”></div>
ᶅςϯϓϨʔτͷhtmlʹϝʔϧͷhtmlจࣈྻΛૠೖ ϝʔϧඳը·ͰͷྲྀΕᶅ template_message.html <div class=“mail-message-content“>%s</div> ↓ <div class=“mail-message-content“>࣮ࡍͷϝʔϧ༰</div>
ϝʔϧඳը·ͰͷྲྀΕᶆ ᶆ߹ͨ͠htmlจࣈྻΛWebViewͰඳը͢Δ ConversationViewFragment.java mWebView.loadDataWithBaseURL(mBaseUri, convHtml, "text/html", "utf-8", null);
ϝʔϧඳը·ͰͷྲྀΕᶇ ᶇpadding্ʹϔομʔɾϑολʔViewGroupΛ ɹlayout()Ͱஔ͢Δ
࣮ϙΠϯτ
ConversationContainer • ViewGroupΛΦʔόʔϨΠ ͱͯ͠औΓ࣋ͭ • WebViewͱViewGroupͷ Լʹ͍ΔFrameLayoutతଘࡏ WebView ViewGroup ViewGroup
ConversationContainer
ViewGroupͷಈ͔͠ํ • ϔομʔɾϑολʔWebViewͷεΫϩʔϧʹ࿈ಈ͢Δ • ConversationContainer͕ಈ͔͢ • offsetTopAndBottom()ͰsetTransitionY()Ͱͳ͘layout()
λονΠϕϯτ • ConversationContainerͷλονΠϕϯτͦͷ·· WebViewʹͤ͞Δ • ScrollViewͷonInterceptTouchEventΛࢀߟʹͯ͠ ViewGroupͷλονΠϕϯτΛ੍ݶ͍ͯ͠Δ
ViewGroupͷϦαΠΫϧ • ConversationContainerͷViewGroupListViewͷΑ͏ʹ ViewΛഁغɾ࠶ੜ͢ΔϦαΠΫϧͷΈ͕ΘΕ͍ͯΔ
ϔομʔλοϓ࣌ͷಈ͖ • ϔομʔΛλοϓ͢ΔͱɺjavascriptͰcssͷstyle.display Λݺͼɺදࣔ/ඇදࣔΛΓସ͑Δ λοϓ
ඳըͷऴྃͷड͚औΓ • ඳըͷऴྃΛcssͷίʔϧόοΫ(webkitAnimationStart) Ͱड͚औΔ • ओʹProgressBarͷඇදࣔͷͨΊʹ͏
εΫϩʔϧόʔ • WebViewͷεΫϩʔϧόʔ Λ͏ͱViewGroupʹ ӅΕͯ͠·͏ͨΊࣗલͰੜ • android:scrollbars=“vertical” ʹͯ͠Έͨঢ়ଶ→
AOSPϝʔϧΞϓϦ͍͢͝
GmailΞϓϦͱҧ͏ͷʁ
͓ͼ • 1݄ʹGmailͷσβΠϯϦχϡʔΞϧ͕ൃද https://jp.techcrunch.com/ 2019/01/30/2019-01-29-gmail-on-mobile- gets-a-fresh-coat-of-material-design-paint/ • ࠓճൺֱͨ͠όʔδϣϯͦͷલͷ8.12.30 (2019/1/24ߋ৽)
GmailΞϓϦͱͷൺֱ AOSPϝʔϧ Gmail
GmailΞϓϦͱͷൺֱ • ػೳɺࡉ͔͍UIͳͲҧ͏ • ϝʔϧৄࡉը໘ͷߏಉ͡
ϔομʔΦʔόʔϨΠʁ • ԡͯ͠͠ʮͯ͢બʯ
• ϔομʔViewGroup WebView্ʹΦʔόʔϨΠ ͞Εͯͦ͏ ϔομʔΦʔόʔϨΠʁ ͜͜͡Όͳ͍ʂ
ϑολʔΦʔόʔϨΠʁ • ζʔϜΠϯͨ͠ঢ়ଶ
ϑολʔΦʔόʔϨΠʁ • ϑολʔViewGroup WebView্ʹΦʔόʔϨΠ ͞Εͯͦ͏
GmailΞϓϦͱͷൺֱ • WebView্ʹϔομʔɾϑολʔViewGroup ͕ΦʔόʔϨΠ͞Ε͍ͯΔ • AOSPϝʔϧͱಉ͡ߏͷՄೳੑ͕ߴ͍
χϡʔεΞϓϦͷԠ༻
ϓϩμΫτೖ·ͰͷྲྀΕ • ͕ൃੜɺݪҼΛݕূ • AOSPʹࢀߟʹͳΔ࣮͕ͳ͍͔୳͢ • ෦࣮ΛಡΈਐΊΔ • ࠷ݶͰಈ͘ΞϓϦΛ࡞ͬͯݕূ •
ϓϩμΫτʹೖ
ϓϩμΫτೖ • ϑολʔͷΈඞཁͳը໘͔Β࣮ࢪ WebView ϑολʔViewGroup
ࢀߟʹ͠ͳ͔ͬͨͱ͜Ζ
ࢀߟʹ͠ͳ͔ͬͨͱ͜Ζ • ViewͷϦαΠΫϧΛ͍ͯ͠ͳ͍ ˠࠓճͷέʔεͰෆཁ
ࢀߟʹ͠ͳ͔ͬͨͱ͜Ζ • WebViewඳըऴྃͷίʔϧόοΫ DOMContentLoadedΛ͏ ˠૣ͍ɺ؆୯
ࢀߟʹ͠ͳ͔ͬͨͱ͜Ζ • ViewGroupͷҠಈlayout()Ͱͳ͘ ViewCompat.offsetTopAndBottom()Λ༻ ˠίʔυͷ໌֬Խ ˠsetTransitionYΞχϝʔγϣϯ͖
࣮ࡍͲ͏ͩͬͨͷ͔
࠾༻ͯ͠Α͔ͬͨ͜ͱ • ͷରॲ͕Ͱ͖ͨ • ඳը͕एׯૣ͘ͳͬͨ
࠾༻ͯ͠େมͩͬͨ͜ͱ • Մಡੑ͕Լ͕Γɺϝϯςίετ͕૿͑ͨ • ಋೖ͢Δ·Ͱ͕͔͔࣌ؒͬͨ ɾରԠํ๏ͷݕূ࣌ؒ ɾಋೖํ๏ͷݕূ࣌ؒ
ਅࣅ͖͔͢Ͳ͏͔ • ݕ౼ͷ༨͋Δ͕࠾༻ίετߴ͍ • WebView in ScrollViewͷϦεΫΛߟ͑Δ
͠WebView+ViewGroup ͨ͘͠ͳͬͨΒʁ
͠ඞཁʹഭΒΕͨΒ… • WebViewΛΊΔʢ࠷ਪʣ • WebViewͷΈʹ͢Δʢڧ͘ਪʣ • AOSPϝʔϧํࣜΛࢀߟʹ͢Δʢਪʣ
͠ඞཁʹഭΒΕͨΒ… • https://github.com/angebagui/medium-textview/ https://github.com/m7mdra/HtmlRecycler ͷϥΠϒϥϦΛͬͯΈΔʢرʣ • ৽͍͠ΓํΛߟ͑Δʢେ݀ʣ • ScrollViewʹWebViewΛೖΕΔʢඇਪʣ
αϯϓϧΞϓϦ
αϯϓϧΞϓϦ • https://github.com/ogapants/WebViewWithViewGroup • ̎ͭͷํ๏ͰWebView+ButtonΛ࣮ݱ - WebView in ScrollView
- WebView only
αϯϓϧΞϓϦཁ݅ • 1͔Β260·Ͱදࣔ͢ΔHTML • WebViewͷ্ԼʹButton • શମΛεΫϩʔϧͰ͖Δ WebView
Button Button 1 2 3 … 258 259 260
ํ๏ᶃ WebView in ScrollView
WebView in ScrollView • ్தͰΕΔ • <ScrollView> <LinerLayout> ɹɹɹ<Button> <WebView>
<Button> </LinerLayout> <ScrollView>
WebView in ScrollView • ࠶ݱΤϛϡϨʔλ Pixel2XLɺNexus6PʢόʔδϣϯدΒͣʣ • ඇ࠶ݱΤϛϡϨʔλ Pixel2ɺNexus5XͳͲʢόʔδϣϯدΒͣʣ •
࣮ػ࠶ݱੑ͕ᐆດ
ํ๏ᶄ WebView only
WebView only • ͳ͘දࣔ͞ΕΔ • <ArticleContainer> <ArticleWebView> <Button> <Button> </ArticleContainer>
WebView only • ArticleContainerͷ࣮ • ϔομʔͱϑολʔΛεΫϩʔϧͤ͞Δ fun dispatchScroll(oldScrollY:
Int, scrollY: Int) { this.offsetY = scrollY val oldScrollYAbs = Math.abs(oldScrollY) val scrollYAbs = Math.abs(scrollY) val offset = oldScrollYAbs - scrollYAbs ViewCompat.offsetTopAndBottom(header, offset) ViewCompat.offsetTopAndBottom(footer, offset) }
WebView only • ςϯϓϨʔτHTMLͷ࣮ <!DOCTYPE html>ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ <html>ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ <script
type="text/javascript">ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ window.addEventListener("DOMContentLoaded", function () {ɹɹɹɹɹɹ var contentHeight = document.getElementById(“content").offsetHeight; window.JS._onDomContentLoaded(contentHeight);ɹɹɹɹɹɹɹɹɹ });ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ </script>
• ςϯϓϨʔτHTMLͷ࣮ WebView only <body> <div id="header-spacer" style="height: %spx;"></div> <div
id="content"> %s </div>ɹɹɹɹɹɹɹɹɹɹɹɹɹ <div id="footer-spacer" style="height: %spx;"></div> </body>ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ </html>ɹɹɹɹɹɹ
͍͞͝ʹ
͓͞Β͍ • WebViewͰεΫϩʔϧͤ͞Δ • ViewGroup࿈ಈ • ViewGroupͷߴ͞cssͰpadding WebView ViewGroup ViewGroup
padding padding
·ͱΊ • AOSPݟͷմͳͷͰ͏·͘ར༻͠Α͏ • AOSPϝʔϧΞϓϦͷϝʔϧৄࡉը໘ͷඳըͷΈ͍͢͝ • ඞཁ࠷ݶͷߏΛ࡞ͬͯ࠶ݱੑΛݟͯɺ࠷ݶͷ࣮ͰΔ͜ͱ Λ֬ೝͯ͠ɺطଘίʔυΛՃຯͭͭ͠ɺϓϩμΫτʹೖ͠Α͏ • ScrollViewͷதʹWebViewΛೖΕΔͷආ͚Α͏
࠾༻ͬͯ·͢ https://s.nikkei.com/s_android