Upgrade to Pro — share decks privately, control downloads, hide ads and more …

WebView+ViewGroupを実現するAOSPメールアプリの内部実装とニュースアプリへの応用 / DroidKaigi2019

92f3264246c62b106ae1f85fea25f57a?s=47 ogapants
February 07, 2019

WebView+ViewGroupを実現するAOSPメールアプリの内部実装とニュースアプリへの応用 / DroidKaigi2019

92f3264246c62b106ae1f85fea25f57a?s=128

ogapants

February 07, 2019
Tweet

Transcript

  1. WebView+ViewGroupΛ࣮ݱ ͢ΔAOSPϝʔϧΞϓϦͷ಺෦ ࣮૷ͱχϡʔεΞϓϦ΁ͷԠ༻ 2019/02/08 DroidKaigi @ogapants  

  2. ࣗݾ঺հ • ͓͕ͺΜ@ogapants • ೔ຊܦࡁ৽ฉࣾ • ٕज़ॻయͰνʔϜվળͱAndroidStudioͷ
 Tipsʹ͍ͭͯॻ͖·ͨ͠ɻnoteͰݟΕ·͢ʂ
 https://goo.gl/AWv7v1 

    
  3. WebView+ViewGroupΛ࣮ݱ ͢ΔAOSPϝʔϧΞϓϦͷ಺෦ ࣮૷ͱχϡʔεΞϓϦ΁ͷԠ༻  

  4. ͍͖ͳΓͰ͕͢ • ͜͏͍͏ߏ੒ͷը໘ɺͲ͏΍ͬͯ
 εΫϩʔϧͤ͞·͔͢ʁ TextView WebView Image
 View Text View

    TextView  
  5. ͍͖ͳΓͰ͕͢ • ScrollViewͰ
 ғͬͪΌ͍·ͤΜ͔ʁ TextView WebView Image
 View Text View

    TextView ScrollView?  
  6. • ScrollViewͰWebViewΛғͬͯ͸͍͚·ͤΜ • ғ͏ͱͲ͏ͳΔͷʁ • ͡Ό͋Ͳ͏͢Ε͹͍͍ͷʁ  

  7. ͜ͷൃදͰ࿩͢͜ͱ • ͳͥScrollViewͰWebViewΛғ͏ͷ͕Α͘ͳ͍͔ • AOSPϝʔϧͰWebView͸Ͳ͏࢖ΘΕ͍ͯΔͷ͔ • Ͳ͏Ԡ༻ͨ͠ͷ͔  

  8. AOSPϝʔϧΞϓϦͱ͸  

  9. AOSPͱ͸ • Android Open Source Project • ࣗ༝ʹӾཡɺ࠶ར༻͕Մೳ • OSपลͷ৘ใɺ։ൃπʔϧɺαϯϓϧΞϓϦͳͲ΋ఏڙ

    • ϒϥ΢β΍ి୎ɺΪϟϥϦʔΞϓϦͳͲ΋  
  10. AOSPϝʔϧΞϓϦͱ͸  

  11. AOSPϝʔϧΞϓϦͱ͸ • AOSPʹ্͕ͬͯΔϝʔϧΞϓϦ • 2014೥͝Ζ·ͰҰ෦୺຤Ͱ͸ϓϦΠϯετʔϧ • ࠓճ͸ϝʔϧৄࡉը໘ͷ࿩ • ·ͩΞοϓσʔτ͞Ε͍ͯΔ 

    
  12. AOSPϝʔϧΞϓϦϦϙδτϦ • ΞΧ΢ϯτपΓ
 https://android.googlesource.com/platform/packages/ apps/Email/ • ϝΠϯػೳ
 https://android.googlesource.com/platform/packages/ apps/UnifiedEmail/
 

    
  13. AOSPϝʔϧΞϓϦϦϙδτϦ • ͲͪΒ΋EclipseͷϑΝΠϧߏ੒ • ଍Γͳ͍ίϯϙʔωϯτଟ਺  

  14. ඇެࣜAOSPϝʔϧΞϓϦ • https://github.com/jinkg/YalinEmail • ඞཁͳίϯϙʔωϯτ܈ΛαϒϞδϡʔϧԽ͍ͯ͠Δ • AndroidStudioͰϏϧυͰ͖ΔΑ͏ʹͨ͠ඇެࣜΞϓϦ  

  15. [ิ଍]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/  
  16. [ิ଍]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/  
  17. ಺෦࣮૷Λ௥͏ܦҢ  

  18. ͜Ε·Ͱͷݸผهࣄը໘ͷߏ੒ TextView WebView Image
 View Text View TextView ScrollView ϔομʔViewGroupɿهࣄͷλΠτϧͳͲ

    ίϯςϯπWebViewɿهࣄ಺༰ ϑολʔViewGroupɿؔ࿈هࣄͳͲ  
  19. ࣮ࡍʹى͖ͨ໰୊  

  20. ࣮ࡍʹى͖ͨ໰୊ᶃ • Ұ෦୺຤Ͱ௿ස౓Ͱ
 هࣄ͕੾Εͯදࣔ͞ΕΔ • (WebViewͷΞοϓσʔτ
 ʹΑͬͯ࢑ఆղܾ)
  

  21. ࣮ࡍʹى͖ͨ໰୊ᶄ • Ұ෦୺຤Ͱ௿ස౓ͰIllegalStateException
 >Unable to create layer for WebView •

    (Ұ෦୺຤ͷϋʔυ΢ΣΞΞΫηϥϨʔγϣϯOFF
 Ͱ࢑ఆղܾ)  
  22. ࣮ࡍʹى͖ͨ໰୊ • ͍ͣΕ΋࢑ఆରԠͰ͔͠ͳ͍… • ߃ٱରԠ͢΂͘GoogleͷΤϯδχΞʹ࣭໰  

  23. ࣮ࡍʹى͖ͨ໰୊ • ScrollView͸WebViewΛೖΕΔ͜ͱΛ૝ఆͯ͠
 ࡞͍ͬͯͳ͍ʂ by GoogleΤϯδχΞ  

  24. ߟ͑ͨղܾࡦ  

  25. ߟ͑ͨղܾࡦ • WebViewΛ΍ΊΔ
 ˠશͯωΠςΟϒʹ͢Δɹ
 ˠ Өڹൣғ͕େ͖͘ࠔ೉  

  26. ߟ͑ͨղܾࡦ • WebViewͷΈʹ͢Δɹ
 ˠViewGroup෦෼ͷHTMLԽ
 ˠ ը໘ͷঢ়ଶ͕ଟ͘ࠔ೉  

  27. ߟ͑ͨղܾࡦ • AppBarLayoutͷ࢓૊ΈΛར༻͢Δ
 ˠNestedScrollͰಈ͔͢
 ˠ ٕज़తʹࠔ೉
  

  28. ߟ͑ͨղܾࡦ • ϝʔϧΞϓϦΛࢀߟʹ͢Δ
 ˠ WebViewΛ࢖͍ͬͯΔ͸ͣ
 ˠ AOSPΛݟΕ͹͍͚ͦ͏ʁ
 ˠ deep dive

     
  29. ͪͳΈʹ • https://developer.android.com/reference/android/widget/ ScrollView • >Never add a RecyclerView or

    ListView to a scroll view. • WebViewʹ͍ͭͯͷهࡌ͸ແ͠…  
  30. WebView+ViewGroupΛ ࣮ݱ͢ΔAOSPϝʔϧΞϓϦͷ ಺෦࣮૷  

  31. AOSPϝʔϧΞϓϦͰͷߏ੒   • ֬ೝͨ͠όʔδϣϯ͸
 https://android.googlesource.com/platform/ packages/apps/UnifiedEmail/
 ͷϦϏδϣϯ `1668ada` •

    Ϗϧυ؀ڥ͸jinkg/YalinEmail
  32. AOSPϝʔϧΞϓϦͰͷߏ੒ ϔομʔViewGroup ίϯςϯπWebView ϑολʔViewGroup  

  33. AOSPϝʔϧΞϓϦͰͷߏ੒ WebView in ScrollView AOSPϝʔϧΞϓϦ WebView ViewGroup ScrollView ViewGroup WebView

    ViewGroup ViewGroup  
  34. AOSPϝʔϧΞϓϦͰͷߏ੒ • WebViewͰεΫϩʔϧͤ͞Δ • ViewGroup΋࿈ಈ • ViewGroupͷߴ͞෼cssͰpadding WebView ViewGroup ViewGroup

    padding padding  
  35. ϝʔϧඳը·ͰͷྲྀΕ ᶃWebViewʹΦʔόʔϨΠ͍ͤͨ͞ViewGroupΛmeasure()ͯ͠ߴ͞ΛଌΔ ᶄςϯϓϨʔτͷhtmlʹcssͰpaddingΛ͚ͭΔ ᶅςϯϓϨʔτͷhtmlʹϝʔϧͷhtmlจࣈྻΛૠೖ ᶆ߹੒ͨ͠htmlจࣈྻΛWebViewͰඳը͢Δ ᶇpadding্ʹϔομʔɾϑολʔViewGroupΛlayout()Ͱ഑ஔ͢Δ  

  36. ϝʔϧඳը·ͰͷྲྀΕᶃ ᶃWebViewʹΦʔόʔϨΠ͍ͤͨ͞ViewGroupΛ
 ɹmeasure()ͯ͠ߴ͞ΛଌΔ
 
 ɹˠmeasure()…ViewͷαΠζΛܭଌ͢Δ
 ɹˠgetMeasuredHeight()Ͱऔಘ  

  37. ᶄςϯϓϨʔτͷhtmlʹcssͰpaddingΛ͚ͭΔ
 ϝʔϧඳը·ͰͷྲྀΕᶄ template_conversation_upper.html <div … style="height: %spx;”></div>
 ↓ ViewGroup෼ͷߴ͞ <div

    … style="height: 288px;”></div>  
  38. ᶅςϯϓϨʔτͷhtmlʹϝʔϧͷhtmlจࣈྻΛૠೖ ϝʔϧඳը·ͰͷྲྀΕᶅ template_message.html <div class=“mail-message-content“>%s</div>
 ↓
 <div class=“mail-message-content“>࣮ࡍͷϝʔϧ಺༰</div>  

  39. ϝʔϧඳը·ͰͷྲྀΕᶆ ᶆ߹੒ͨ͠htmlจࣈྻΛWebViewͰඳը͢Δ   ConversationViewFragment.java mWebView.loadDataWithBaseURL(mBaseUri, convHtml, "text/html", "utf-8", null);

  40. ϝʔϧඳը·ͰͷྲྀΕᶇ ᶇpadding্ʹϔομʔɾϑολʔViewGroupΛ
 ɹlayout()Ͱ഑ஔ͢Δ  

  41. ࣮૷ϙΠϯτ  

  42. ConversationContainer • ViewGroupΛΦʔόʔϨΠ
 ͱͯ͠औΓ࣋ͭ • WebViewͱViewGroupͷ
 Լʹ͍ΔFrameLayoutతଘࡏ WebView ViewGroup ViewGroup

    ConversationContainer  
  43. ViewGroupͷಈ͔͠ํ • ϔομʔɾϑολʔ͸WebViewͷεΫϩʔϧʹ࿈ಈ͢Δ • ConversationContainer͕ಈ͔͢ • offsetTopAndBottom()Ͱ΋setTransitionY()Ͱ΋ͳ͘layout()  

  44. λονΠϕϯτ • ConversationContainer΁ͷλονΠϕϯτ͸ͦͷ·· WebViewʹ఻೻ͤ͞Δ • ScrollViewͷonInterceptTouchEventΛࢀߟʹͯ͠ ViewGroup΁ͷλονΠϕϯτΛ੍ݶ͍ͯ͠Δ  

  45. ViewGroupͷϦαΠΫϧ • ConversationContainer಺ͷViewGroup͸ListViewͷΑ͏ʹ ViewΛഁغɾ࠶ੜ੒͢ΔϦαΠΫϧͷ࢓૊Έ͕࢖ΘΕ͍ͯΔ  

  46. ϔομʔλοϓ࣌ͷಈ͖ • ϔομʔΛλοϓ͢ΔͱɺjavascriptͰcssͷstyle.display Λݺͼɺදࣔ/ඇදࣔΛ੾Γସ͑Δ λοϓ  

  47. ඳըͷऴྃͷड͚औΓ • ඳըͷऴྃΛcssͷίʔϧόοΫ(webkitAnimationStart) Ͱड͚औΔ • ओʹProgressBarͷඇදࣔͷͨΊʹ࢖͏  

  48. εΫϩʔϧόʔ • WebViewͷεΫϩʔϧόʔ
 Λ࢖͏ͱViewGroupʹ
 ӅΕͯ͠·͏ͨΊࣗલͰੜ੒ • android:scrollbars=“vertical”
 ʹͯ͠Έͨঢ়ଶ→
  

  49. AOSPϝʔϧΞϓϦ͍͢͝  

  50. GmailΞϓϦͱ͸ҧ͏ͷʁ  

  51. ͓࿳ͼ • 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ߋ৽) 

    
  52. GmailΞϓϦͱͷൺֱ AOSPϝʔϧ Gmail  

  53. GmailΞϓϦͱͷൺֱ • ػೳɺࡉ͔͍UIͳͲ͸ҧ͏ • ϝʔϧৄࡉը໘ͷߏ੒͸ಉ͡  

  54. ϔομʔ͸ΦʔόʔϨΠʁ   • ௕ԡͯ͠͠ʮ͢΂ͯબ୒ʯ

  55. • ϔομʔViewGroup͸
 WebView্ʹΦʔόʔϨΠ
 ͞Εͯͦ͏ ϔομʔ͸ΦʔόʔϨΠʁ   ͜͜͡Όͳ͍ʂ

  56. ϑολʔ͸ΦʔόʔϨΠʁ   • ζʔϜΠϯͨ͠ঢ়ଶ

  57. ϑολʔ͸ΦʔόʔϨΠʁ   • ϑολʔViewGroup΋
 WebView্ʹΦʔόʔϨΠ
 ͞Εͯͦ͏

  58. GmailΞϓϦͱͷൺֱ • WebView্ʹϔομʔɾϑολʔViewGroup ͕ΦʔόʔϨΠ͞Ε͍ͯΔ • AOSPϝʔϧͱಉ͡ߏ੒ͷՄೳੑ͕ߴ͍  

  59. χϡʔεΞϓϦ΁ͷԠ༻  

  60. ϓϩμΫτ౤ೖ·ͰͷྲྀΕ • ໰୊͕ൃੜɺݪҼΛݕূ • AOSPʹࢀߟʹͳΔ࣮૷͕ͳ͍͔୳͢ • ಺෦࣮૷ΛಡΈਐΊΔ • ࠷௿ݶͰಈ͘ΞϓϦΛ࡞ͬͯݕূ •

    ϓϩμΫτʹ౤ೖ  
  61. ϓϩμΫτ౤ೖ • ϑολʔͷΈඞཁͳը໘͔Β࣮ࢪ WebView ϑολʔViewGroup  

  62. ࢀߟʹ͠ͳ͔ͬͨͱ͜Ζ  

  63. ࢀߟʹ͠ͳ͔ͬͨͱ͜Ζ • ViewͷϦαΠΫϧΛ͍ͯ͠ͳ͍
 ˠࠓճͷέʔεͰ͸ෆཁ  

  64. ࢀߟʹ͠ͳ͔ͬͨͱ͜Ζ • WebViewඳըऴྃͷίʔϧόοΫ͸ DOMContentLoadedΛ࢖͏
 ˠૣ͍ɺ؆୯  

  65. ࢀߟʹ͠ͳ͔ͬͨͱ͜Ζ • ViewGroupͷҠಈ͸layout()Ͱ͸ͳ͘ ViewCompat.offsetTopAndBottom()Λ࢖༻
 ˠίʔυͷ໌֬Խ
 ˠsetTransitionY͸Ξχϝʔγϣϯ޲͖  

  66. ࣮ࡍͲ͏ͩͬͨͷ͔  

  67. ࠾༻ͯ͠Α͔ͬͨ͜ͱ • ໰୊΁ͷରॲ͕Ͱ͖ͨ • ඳը଎౓͕एׯૣ͘ͳͬͨ  

  68. ࠾༻ͯ͠େมͩͬͨ͜ͱ • Մಡੑ͕Լ͕Γɺϝϯςίετ͕૿͑ͨ • ಋೖ͢Δ·Ͱ͕͔͔࣌ؒͬͨ
 ɾରԠํ๏ͷݕূ࣌ؒ
 ɾಋೖํ๏ͷݕূ࣌ؒ  

  69. ਅࣅ͢΂͖͔Ͳ͏͔ • ݕ౼ͷ༨஍͸͋Δ͕࠾༻ίετ͸ߴ͍ • WebView in ScrollViewͷϦεΫΛߟ͑Δ  

  70. ΋͠WebView+ViewGroup ͨ͘͠ͳͬͨΒʁ  

  71. ΋͠ඞཁʹഭΒΕͨΒ… • WebViewΛ΍ΊΔʢ࠷΋ਪ঑ʣ • WebViewͷΈʹ͢Δʢڧ͘ਪ঑ʣ • AOSPϝʔϧํࣜΛࢀߟʹ͢Δʢ΍΍ਪ঑ʣ  

  72. ΋͠ඞཁʹഭΒΕͨΒ… • https://github.com/angebagui/medium-textview/
 https://github.com/m7mdra/HtmlRecycler
 ͷϥΠϒϥϦΛ࢖ͬͯΈΔʢر๬ʣ • ৽͍͠΍ΓํΛߟ͑Δʢେ݀ʣ • ScrollViewʹWebViewΛೖΕΔʢඇਪ঑ʣ 

    
  73. αϯϓϧΞϓϦ  

  74. αϯϓϧΞϓϦ • https://github.com/ogapants/WebViewWithViewGroup
 • ̎ͭͷํ๏ͰWebView+ButtonΛ࣮ݱ
 - WebView in ScrollView 


    - WebView only  
  75. αϯϓϧΞϓϦཁ݅ • 1͔Β260·Ͱදࣔ͢ΔHTML • WebViewͷ্ԼʹButton • શମΛεΫϩʔϧͰ͖Δ   WebView

    Button Button 1 2 3 … 258 259 260
  76. ํ๏ᶃ
 WebView in ScrollView  

  77. WebView in ScrollView • ్தͰ੾ΕΔ • <ScrollView> <LinerLayout> ɹɹɹ<Button> <WebView>

    <Button> </LinerLayout> <ScrollView>  
  78. WebView in ScrollView • ࠶ݱΤϛϡϨʔλ
 Pixel2XLɺNexus6PʢόʔδϣϯدΒͣʣ • ඇ࠶ݱΤϛϡϨʔλ
 Pixel2ɺNexus5XͳͲʢόʔδϣϯدΒͣʣ •

    ࣮ػ͸࠶ݱੑ͕ᐆດ  
  79. ํ๏ᶄ WebView only  

  80. WebView only • ໰୊ͳ͘දࣔ͞ΕΔ • <ArticleContainer> <ArticleWebView> <Button> <Button> </ArticleContainer>

     
  81. 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) }
  82. 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>
  83. • ςϯϓϨʔτ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>ɹɹɹɹɹɹ  
  84. ͍͞͝ʹ  

  85. ͓͞Β͍ • WebViewͰεΫϩʔϧͤ͞Δ • ViewGroup΋࿈ಈ • ViewGroupͷߴ͞෼cssͰpadding WebView ViewGroup ViewGroup

    padding padding  
  86. ·ͱΊ • AOSP͸஌ݟͷմͳͷͰ͏·͘ར༻͠Α͏ • AOSPϝʔϧΞϓϦͷϝʔϧৄࡉը໘ͷඳըͷ࢓૊Έ͸͍͢͝ • ඞཁ࠷௿ݶͷߏ଄Λ࡞ͬͯ࠶ݱੑΛݟͯɺ࠷௿ݶͷ࣮૷Ͱ௚Δ͜ͱ Λ֬ೝͯ͠ɺطଘίʔυΛՃຯͭͭ͠ɺϓϩμΫτʹ౤ೖ͠Α͏ • ScrollViewͷதʹWebViewΛೖΕΔͷ͸ආ͚Α͏

     
  87. ࠾༻΍ͬͯ·͢ https://s.nikkei.com/s_android