Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

AOSPϝʔϧΞϓϦͱ͸  

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

AOSPϝʔϧΞϓϦͱ͸  

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

[ิ଍]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/  

Slide 16

Slide 16 text

[ิ଍]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/  

Slide 17

Slide 17 text

಺෦࣮૷Λ௥͏ܦҢ  

Slide 18

Slide 18 text

͜Ε·Ͱͷݸผهࣄը໘ͷߏ੒ TextView WebView Image
 View Text View TextView ScrollView ϔομʔViewGroupɿهࣄͷλΠτϧͳͲ ίϯςϯπWebViewɿهࣄ಺༰ ϑολʔViewGroupɿؔ࿈هࣄͳͲ  

Slide 19

Slide 19 text

࣮ࡍʹى͖ͨ໰୊  

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

࣮ࡍʹى͖ͨ໰୊ᶄ • Ұ෦୺຤Ͱ௿ස౓ͰIllegalStateException
 >Unable to create layer for WebView • (Ұ෦୺຤ͷϋʔυ΢ΣΞΞΫηϥϨʔγϣϯOFF
 Ͱ࢑ఆղܾ)  

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

ߟ͑ͨղܾࡦ  

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

ᶄςϯϓϨʔτͷhtmlʹcssͰpaddingΛ͚ͭΔ
 ϝʔϧඳը·ͰͷྲྀΕᶄ template_conversation_upper.html
 

Slide 38

Slide 38 text

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

 ↓

࣮ࡍͷϝʔϧ಺༰
 

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

࣮૷ϙΠϯτ  

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

AOSPϝʔϧΞϓϦ͍͢͝  

Slide 50

Slide 50 text

GmailΞϓϦͱ͸ҧ͏ͷʁ  

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

χϡʔεΞϓϦ΁ͷԠ༻  

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

ࢀߟʹ͠ͳ͔ͬͨͱ͜Ζ  

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

࣮ࡍͲ͏ͩͬͨͷ͔  

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

αϯϓϧΞϓϦ  

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

ํ๏ᶃ
 WebView in ScrollView  

Slide 77

Slide 77 text

WebView in ScrollView • ్தͰ੾ΕΔ • ɹɹɹ  

Slide 78

Slide 78 text

WebView in ScrollView • ࠶ݱΤϛϡϨʔλ
 Pixel2XLɺNexus6PʢόʔδϣϯدΒͣʣ • ඇ࠶ݱΤϛϡϨʔλ
 Pixel2ɺNexus5XͳͲʢόʔδϣϯدΒͣʣ • ࣮ػ͸࠶ݱੑ͕ᐆດ  

Slide 79

Slide 79 text

ํ๏ᶄ WebView only  

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

• ςϯϓϨʔτHTMLͷ࣮૷ WebView only
%s
ɹɹɹɹɹɹɹɹɹɹɹɹɹ
ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹ ɹɹɹɹɹɹ  

Slide 84

Slide 84 text

͍͞͝ʹ  

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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