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

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

ogapants
February 07, 2019

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

ogapants

February 07, 2019
Tweet

More Decks by ogapants

Other Decks in Technology

Transcript

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


    View full-size slide

  2. ࣗݾ঺հ
    • ͓͕ͺΜ@ogapants
    • ೔ຊܦࡁ৽ฉࣾ
    • ٕज़ॻయͰνʔϜվળͱAndroidStudioͷ

    Tipsʹ͍ͭͯॻ͖·ͨ͠ɻnoteͰݟΕ·͢ʂ

    https://goo.gl/AWv7v1


    View full-size slide

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


    View full-size slide

  4. ͍͖ͳΓͰ͕͢
    • ͜͏͍͏ߏ੒ͷը໘ɺͲ͏΍ͬͯ

    εΫϩʔϧͤ͞·͔͢ʁ
    TextView
    WebView
    Image

    View
    Text
    View
    TextView


    View full-size slide

  5. ͍͖ͳΓͰ͕͢
    • ScrollViewͰ

    ғͬͪΌ͍·ͤΜ͔ʁ
    TextView
    WebView
    Image

    View
    Text
    View
    TextView
    ScrollView?


    View full-size slide


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


    View full-size slide

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


    View full-size slide

  8. AOSPϝʔϧΞϓϦͱ͸


    View full-size slide

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


    View full-size slide

  10. AOSPϝʔϧΞϓϦͱ͸


    View full-size slide

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


    View full-size slide

  12. AOSPϝʔϧΞϓϦϦϙδτϦ
    • ΞΧ΢ϯτपΓ

    https://android.googlesource.com/platform/packages/
    apps/Email/
    • ϝΠϯػೳ

    https://android.googlesource.com/platform/packages/
    apps/UnifiedEmail/



    View full-size slide

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


    View full-size slide

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


    View full-size slide

  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/


    View full-size slide

  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/


    View full-size slide

  17. ಺෦࣮૷Λ௥͏ܦҢ


    View full-size slide

  18. ͜Ε·Ͱͷݸผهࣄը໘ͷߏ੒
    TextView
    WebView
    Image

    View
    Text
    View
    TextView
    ScrollView
    ϔομʔViewGroupɿهࣄͷλΠτϧͳͲ
    ίϯςϯπWebViewɿهࣄ಺༰
    ϑολʔViewGroupɿؔ࿈هࣄͳͲ


    View full-size slide

  19. ࣮ࡍʹى͖ͨ໰୊


    View full-size slide

  20. ࣮ࡍʹى͖ͨ໰୊ᶃ
    • Ұ෦୺຤Ͱ௿ස౓Ͱ

    هࣄ͕੾Εͯදࣔ͞ΕΔ
    • (WebViewͷΞοϓσʔτ

    ʹΑͬͯ࢑ఆղܾ)



    View full-size slide

  21. ࣮ࡍʹى͖ͨ໰୊ᶄ
    • Ұ෦୺຤Ͱ௿ස౓ͰIllegalStateException

    >Unable to create layer for WebView
    • (Ұ෦୺຤ͷϋʔυ΢ΣΞΞΫηϥϨʔγϣϯOFF

    Ͱ࢑ఆղܾ)


    View full-size slide

  22. ࣮ࡍʹى͖ͨ໰୊
    • ͍ͣΕ΋࢑ఆରԠͰ͔͠ͳ͍…
    • ߃ٱରԠ͢΂͘GoogleͷΤϯδχΞʹ࣭໰


    View full-size slide

  23. ࣮ࡍʹى͖ͨ໰୊
    • ScrollView͸WebViewΛೖΕΔ͜ͱΛ૝ఆͯ͠

    ࡞͍ͬͯͳ͍ʂ by GoogleΤϯδχΞ


    View full-size slide

  24. ߟ͑ͨղܾࡦ


    View full-size slide

  25. ߟ͑ͨղܾࡦ
    • WebViewΛ΍ΊΔ

    ˠશͯωΠςΟϒʹ͢Δɹ

    ˠ
    Өڹൣғ͕େ͖͘ࠔ೉


    View full-size slide

  26. ߟ͑ͨղܾࡦ
    • WebViewͷΈʹ͢Δɹ

    ˠViewGroup෦෼ͷHTMLԽ

    ˠ
    ը໘ͷঢ়ଶ͕ଟ͘ࠔ೉


    View full-size slide

  27. ߟ͑ͨղܾࡦ
    • AppBarLayoutͷ࢓૊ΈΛར༻͢Δ

    ˠNestedScrollͰಈ͔͢

    ˠ
    ٕज़తʹࠔ೉



    View full-size slide

  28. ߟ͑ͨղܾࡦ
    • ϝʔϧΞϓϦΛࢀߟʹ͢Δ

    ˠ

    WebViewΛ࢖͍ͬͯΔ͸ͣ

    ˠ

    AOSPΛݟΕ͹͍͚ͦ͏ʁ

    ˠ

    deep dive


    View full-size slide

  29. ͪͳΈʹ
    • https://developer.android.com/reference/android/widget/
    ScrollView
    • >Never add a RecyclerView or ListView to a scroll view.
    • WebViewʹ͍ͭͯͷهࡌ͸ແ͠…


    View full-size slide

  30. WebView+ViewGroupΛ
    ࣮ݱ͢ΔAOSPϝʔϧΞϓϦͷ
    ಺෦࣮૷


    View full-size slide

  31. AOSPϝʔϧΞϓϦͰͷߏ੒


    • ֬ೝͨ͠όʔδϣϯ͸

    https://android.googlesource.com/platform/
    packages/apps/UnifiedEmail/

    ͷϦϏδϣϯ `1668ada`
    • Ϗϧυ؀ڥ͸jinkg/YalinEmail

    View full-size slide

  32. AOSPϝʔϧΞϓϦͰͷߏ੒
    ϔομʔViewGroup
    ίϯςϯπWebView
    ϑολʔViewGroup


    View full-size slide

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


    View full-size slide

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


    View full-size slide

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


    View full-size slide

  36. ϝʔϧඳը·ͰͷྲྀΕᶃ
    ᶃWebViewʹΦʔόʔϨΠ͍ͤͨ͞ViewGroupΛ

    ɹmeasure()ͯ͠ߴ͞ΛଌΔ


    ɹˠmeasure()…ViewͷαΠζΛܭଌ͢Δ

    ɹˠgetMeasuredHeight()Ͱऔಘ


    View full-size slide

  37. ᶄςϯϓϨʔτͷhtmlʹcssͰpaddingΛ͚ͭΔ

    ϝʔϧඳը·ͰͷྲྀΕᶄ
    template_conversation_upper.html



    View full-size slide

  38. ᶅςϯϓϨʔτͷhtmlʹϝʔϧͷhtmlจࣈྻΛૠೖ
    ϝʔϧඳը·ͰͷྲྀΕᶅ
    template_message.html
    %s

    ↓

    ࣮ࡍͷϝʔϧ಺༰


    View full-size slide

  39. ϝʔϧඳը·ͰͷྲྀΕᶆ
    ᶆ߹੒ͨ͠htmlจࣈྻΛWebViewͰඳը͢Δ


    ConversationViewFragment.java
    mWebView.loadDataWithBaseURL(mBaseUri,
    convHtml, "text/html", "utf-8", null);

    View full-size slide

  40. ϝʔϧඳը·ͰͷྲྀΕᶇ
    ᶇpadding্ʹϔομʔɾϑολʔViewGroupΛ

    ɹlayout()Ͱ഑ஔ͢Δ


    View full-size slide

  41. ࣮૷ϙΠϯτ


    View full-size slide

  42. ConversationContainer
    • ViewGroupΛΦʔόʔϨΠ

    ͱͯ͠औΓ࣋ͭ
    • WebViewͱViewGroupͷ

    Լʹ͍ΔFrameLayoutతଘࡏ
    WebView
    ViewGroup
    ViewGroup
    ConversationContainer


    View full-size slide

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


    View full-size slide

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


    View full-size slide

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


    View full-size slide

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


    View full-size slide

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


    View full-size slide

  48. εΫϩʔϧόʔ
    • WebViewͷεΫϩʔϧόʔ

    Λ࢖͏ͱViewGroupʹ

    ӅΕͯ͠·͏ͨΊࣗલͰੜ੒
    • android:scrollbars=“vertical”

    ʹͯ͠Έͨঢ়ଶ→



    View full-size slide

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


    View full-size slide

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


    View full-size slide

  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ߋ৽)


    View full-size slide

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


    View full-size slide

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


    View full-size slide

  54. ϔομʔ͸ΦʔόʔϨΠʁ


    • ௕ԡͯ͠͠ʮ͢΂ͯબ୒ʯ

    View full-size slide

  55. • ϔομʔViewGroup͸

    WebView্ʹΦʔόʔϨΠ

    ͞Εͯͦ͏
    ϔομʔ͸ΦʔόʔϨΠʁ


    ͜͜͡Όͳ͍ʂ

    View full-size slide

  56. ϑολʔ͸ΦʔόʔϨΠʁ


    • ζʔϜΠϯͨ͠ঢ়ଶ

    View full-size slide

  57. ϑολʔ͸ΦʔόʔϨΠʁ


    • ϑολʔViewGroup΋

    WebView্ʹΦʔόʔϨΠ

    ͞Εͯͦ͏

    View full-size slide

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


    View full-size slide

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


    View full-size slide

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


    View full-size slide

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


    View full-size slide

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


    View full-size slide

  63. ࢀߟʹ͠ͳ͔ͬͨͱ͜Ζ
    • ViewͷϦαΠΫϧΛ͍ͯ͠ͳ͍

    ˠࠓճͷέʔεͰ͸ෆཁ


    View full-size slide

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

    ˠૣ͍ɺ؆୯


    View full-size slide

  65. ࢀߟʹ͠ͳ͔ͬͨͱ͜Ζ
    • ViewGroupͷҠಈ͸layout()Ͱ͸ͳ͘
    ViewCompat.offsetTopAndBottom()Λ࢖༻

    ˠίʔυͷ໌֬Խ

    ˠsetTransitionY͸Ξχϝʔγϣϯ޲͖


    View full-size slide

  66. ࣮ࡍͲ͏ͩͬͨͷ͔


    View full-size slide

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


    View full-size slide

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

    ɾରԠํ๏ͷݕূ࣌ؒ

    ɾಋೖํ๏ͷݕূ࣌ؒ


    View full-size slide

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


    View full-size slide

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


    View full-size slide

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


    View full-size slide

  72. ΋͠ඞཁʹഭΒΕͨΒ…
    • https://github.com/angebagui/medium-textview/

    https://github.com/m7mdra/HtmlRecycler

    ͷϥΠϒϥϦΛ࢖ͬͯΈΔʢر๬ʣ
    • ৽͍͠΍ΓํΛߟ͑Δʢେ݀ʣ
    • ScrollViewʹWebViewΛೖΕΔʢඇਪ঑ʣ


    View full-size slide

  73. αϯϓϧΞϓϦ


    View full-size slide

  74. αϯϓϧΞϓϦ
    • https://github.com/ogapants/WebViewWithViewGroup

    • ̎ͭͷํ๏ͰWebView+ButtonΛ࣮ݱ

    - WebView in ScrollView 

    - WebView only


    View full-size slide

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


    WebView
    Button
    Button
    1
    2
    3

    258
    259
    260

    View full-size slide

  76. ํ๏ᶃ

    WebView in ScrollView


    View full-size slide

  77. WebView in ScrollView
    • ్தͰ੾ΕΔ


    ɹɹɹ






    View full-size slide

  78. WebView in ScrollView
    • ࠶ݱΤϛϡϨʔλ

    Pixel2XLɺNexus6PʢόʔδϣϯدΒͣʣ
    • ඇ࠶ݱΤϛϡϨʔλ

    Pixel2ɺNexus5XͳͲʢόʔδϣϯدΒͣʣ
    • ࣮ػ͸࠶ݱੑ͕ᐆດ


    View full-size slide

  79. ํ๏ᶄ
    WebView only


    View full-size slide

  80. WebView only
    • ໰୊ͳ͘දࣔ͞ΕΔ







    View full-size slide

  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)
    }

    View full-size slide

  82. WebView only


    • ςϯϓϨʔτHTMLͷ࣮૷
    ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ
    ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ
    ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ<br/>window.addEventListener("DOMContentLoaded", function () {ɹɹɹɹɹɹ<br/>var contentHeight = document.getElementById(“content").offsetHeight;<br/>window.JS._onDomContentLoaded(contentHeight);ɹɹɹɹɹɹɹɹɹ<br/>});ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ<br/>

    View full-size slide

  83. • ςϯϓϨʔτHTMLͷ࣮૷
    WebView only



    %s
    ɹɹɹɹɹɹɹɹɹɹɹɹɹ

    ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ

    View full-size slide

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


    View full-size slide

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


    View full-size slide

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


    View full-size slide