Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
LayoutManagerをつくろう
Search
consomme
March 10, 2017
Programming
3.1k
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
LayoutManagerをつくろう
DroidKaigi 2017 にて発表した資料です。
consomme
March 10, 2017
More Decks by consomme
See All by consomme
所属チームが変わって取り組んだこと
consomme
0
22
Firebaseでゼロからアプリを作る / Make app from scratch with Firebase
consomme
3
2.2k
Other Decks in Programming
See All in Programming
Claude Code ハーネスDeep Dive – 君はどこまで制御する? -
takateeen_knj
6
4.4k
作れる、でも消せるか?──安全に「枯らして消す」機能削除術 / Drain, Then Delete
chobishiba
3
1.5k
baseline으로 마이그레이션, 리팩토링 안전하게 맡기기
fornewid
1
960
선언형 햅틱 라이브러리 진동을 소개합니다
l2hyunwoo
1
300
AIが生成したコードは読むべきか?抽象化設計とコードの品質保証 / abstraction-design-and-quality
minodriven
16
8.9k
Vapor Mode でアクセシビリティは 壊れないか検証した話
fuqda
1
330
SODA - FACT BOOK(EN)
sodainc
1
220
느린 네트워크와 저사양 디바이스 사용자를 위한 웹뷰 로딩 시간 개선기
kmkim
1
220
React Native에 현대적인 빌드 도구 더하기: Rollipop 구현기
leegeunhyeok
0
180
PyConTW 2026 - AI Coding 不只是工具升級, 區域醫院醫療資訊系統協作開發與資訊團隊轉型實踐
cclai999
0
240
動画プレイヤーはなぜカクつくのか 〜Flutterのレンダリングとネイティブの境界を解剖する〜
naruogram
0
330
Crash Auto Pipelines
veronikapj
1
400
Featured
See All Featured
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.5k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
400
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
980
Documentation Writing (for coders)
carmenintech
77
5.6k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
The Mindset for Success: Future Career Progression
greggifford
PRO
0
560
Unlocking the hidden potential of vector embeddings in international SEO
frankvandijk
0
1k
So, you think you're a good person
axbom
PRO
2
2.3k
Intergalactic Javascript Robots from Outer Space
tanoku
273
28k
The Art of Programming - Codeland 2020
erikaheidi
57
14k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Transcript
LayoutManagerΛͭ͘Ζ͏ consomme / DroidKaigi 2017
ࣗݾհ • ͜ΜͦΊ / ࢁ࡚ ਖ਼ (Tadashi Yamazaki) • ϐΫγϒגࣜձࣾɹAndroidΞϓϦΤϯδχΞ
• Twitter : @consomme72 • Github : consomme • FGO : 071,679,396 • Nintendo Switch : SW-3116-2713-1429
Do you know pixiv ?
pixiv http://www.pixiv.net
Do you know BOOTH ?
BOOTH https://booth.pm
pixivͷ͍ΖΜͳαʔϏε
ԬʹΦϑΟε͕Ͱ͖·ͨ͠
ؒืूத https://www.wantedly.com/companies/pixiv
ΞδΣϯμ 1. RecyclerViewͱLayoutManager 2. RecyclerViewͰView͕ஔ͞ΕΔ·Ͱ 3. LayoutManagerͷத 4. LayoutManagerΛͭͬͯ͘ΈΑ͏
ҙࣄ߲ • Support Library 25.2.0 લఏͷ͓Ͱ͢ • ࠓޙόʔδϣϯΞοϓͯ͠શવҧ͏࣮ʹมΘΔՄೳੑ େ͍ʹ͋Γ·͢ •
GoogleઌੜΛ৴͡Α • ͍Ζ͍Ζઆ໌͕ෆ͍ͯͨ͠Γؒҧ͍ͬͯΔՄೳੑ ͋Γ·͢ • RecyclerViewͷίʔυશ෦ݟΔͷͱ͔ແཧ
1. RecyclerViewͱLayoutManager
RecyclerView is Կ • A flexible view for providing a
limited window into a large data set. • ڊେͳσʔληοτΛݶΒΕͨྖҬʹฒΔͨΊͷ View • ListViewGridViewͰͰ͖ͳ͔ͬͨॲཧ͕Մೳ • σʔλͷछྨͰViewΛม͑Δͱ͔͕؆୯ • Ξχϝʔγϣϯͱ͔ࣗಈͰͬͯ͘ΕΔ • ͦͷ͔ΘΓࣗલͰ͍Ζ͍Ζ༻ҙ͠ͳ͍ͱ͍͚ͳ͍ • ۠Γઢͱ͔λοϓΠϕϯτͱ͔
LayoutManager is Կ • RecyclerViewʹ͓͍ͯɺࢠViewΛͲͷΑ͏ʹஔ͢Δ ͔Λܾఆ͢Δͷ • ࢠViewͷαΠζܭࢉɺฒํɺεΫϩʔϧʹΑΔView ͷϦαΠΫϧͳͲΛ੍ޚ͍ͯ͠Δ •
LayoutManagerΛมߋ͢ΕɺRecyclerViewAdapter ͷมߋΛ͢Δ͜ͱͳ͘ϨΠΞτͷมߋ͕Մೳ • ListViewGridViewͰෆՄೳ
Ұൠతͳ RecyclerView ͷ͍ํ RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(new SampleRecyclerAdapter());
setLayoutManager(LayoutManager) 1/2 public void setLayoutManager(LayoutManager layout) { if (layout ==
mLayout) { return; } stopScroll(); if (mLayout != null) { if (mItemAnimator != null) { mItemAnimator.endAnimations(); } mLayout.removeAndRecycleAllViews(mRecycler); mLayout.removeAndRecycleScrapInt(mRecycler); mRecycler.clear(); if (mIsAttached) { mLayout.dispatchDetachedFromWindow(this, mRecycler); } mLayout.setRecyclerView(null); mLayout = null; } else { mRecycler.clear(); } εΫϩʔϧΛࢭΊΔ ΞχϝʔγϣϯΛࢭΊΔ ࢠ7JFXΛͯ͢ফ͢ EFUBDI͢Δ
setLayoutManager(LayoutManager) 2/2 mChildHelper.removeAllViewsUnfiltered(); mLayout = layout; if (layout != null)
{ if (layout.mRecyclerView != null) { throw new IllegalArgumentException("LayoutManager " + layout + " is already attached to a RecyclerView: " + layout.mRecyclerView); } mLayout.setRecyclerView(this); if (mIsAttached) { mLayout.dispatchAttachedToWindow(this); } } mRecycler.updateViewCacheSize(); requestLayout(); } -BZPVU.BOBHFSʹ 3FDZDMFS7JFXΛηοτ 3FDZDMFS7JFXʹ -BZPVU.BOBHFSΛηοτ ϨΠΞτΛ࠶ඳը
AdapterͱRecycler • RecyclerView.Adapter • ࢠViewͷσʔλͷඥ͚Λߦ͏Ϋϥε • σʔλͷछྨʹΑͬͯViewHolderΛ͍͚ͯෳ ͷViewΛ͍͚Δ͜ͱ͕Մೳ • RecyclerView.Recycler
• ඇදࣔͱͳͬͨViewΛ࠶ར༻͢ΔͨΊʹอ͍࣋ͯ͠ ΔΫϥε
2. RecyclerViewͰView͕ஔ͞ΕΔ·Ͱ
RecyclerView extends ViewGroup • RecyclerViewViewGroupͷαϒΫϥεͳͷͰɺඳը ॲཧͷํ๏جຊతʹҰൠతͳViewͱಉ͡ • onMeasure ͰࢠViewͷαΠζΛܾఆ •
onLayout ͰࢠViewΛฒΔ
RecyclerViewʹ͓͚ΔࢠViewͷαΠζଌఆ • Support Library 23.2.0 ΑΓɺRecyclerViewʹ WRAP_CONTENT ͕͑ΔΑ͏ʹͳͬͨ • WRAP_CONTENT
Λ͏ʹɺLayoutManagerଆͰ setAutoMeasuredEnabled(true) Λࢦఆ͢Δඞཁ͋Γ • ٯʹݴ͑ɺ͜Ε͕trueʹͳ͍ͬͯͳ͍߹ WRAP_CONTENT ͑ͳ͍ʢϨΠΞτ่͕Ε Δʣ
setAutoMeasureEnabled ͷʑ͍͠આ໌ https://developer.android.com/reference/android/support/v7/widget/RecyclerView.LayoutManager.html#setAutoMeasureEnabled(boolean)
setAutoMeasureEnabled ͷ؆୯ͳઆ໌ • RecyclerViewLayoutManager͕ࣗಈͰViewͷαΠζΛܭࢉ͢Δ͔Ͳ ͏͔ΛܾΊΔ • trueΛηοτͨ͠߹ • ࣗಈͰViewͷαΠζܭࢉΛߦ͏ •
WRAP_CONTENT Λ༗ޮʹ͚ͨ͠Εtrueʹ͢Δ • falseΛηοτͨ͠߹ • ViewͷαΠζܭࢉ RecyclerView#onMeasure ʹॲཧΛॻ͘ • ॻ͔ͳ͍ͱView͕දࣔ͞Εͳ͍ • ΧελϚΠζͨ͠ܭࢉϩδοΫΛ͍͍ͨ߹ʹ͏ • σϑΥϧτfalseʹͳ͍ͬͯΔͷͰҙ
setAutoMeasureEnabled(true) ͷ߹ͷॲཧ 1/2 1. LayoutManager#onMeasure Λ࣮ߦ͠ɺRecyclerView ͷαΠζ͕ݻఆʢMATCH_PARENT or dpࢦఆʣͷ߹ ͦ͜Ͱऴྃ
2. αΠζ͕ܾ·͍ͬͯͳ͍߹ɺ LayoutManager#onLayoutChildren ʹͯࢠViewͷ heightͱwidthΛܭࢉ͢Δ
setAutoMeasureEnabled(true) ͷ߹ͷॲཧ 2/2 3. setMeasuredDimensionFromChildren Ͱɺ RecyclerViewͷmarginpaddingΛߟྀͯ͠width ͱheightΛܾఆ͢Δ LayoutManager#setMeasuredDimension Λoverride
ͯ͠ɺࣗಈܭࢉͱҧ͏Λઃఆ͢Δ͜ͱ͕Ͱ͖Δ 4. ܭࢉ͕ऴΘͬͨΒ RecyclerView#onLayout ͕ݺΕͯ View͕ஔ͞ΕΔ
3. LayoutManagerͷத
LayoutManagerͷओͳϝιου • abstractϝιου • generateDefaultLayoutParams • abstract͡Όͳ͍͚Ͳ࣮ඞਢͳϝιου • onLayoutChildren •
canScrollHorizontally / canScrollVertically • scrollHorizontallyBy / scrollVerticallyBy • ͦͷଞॏཁϝιου • scrollToPosition • smoothScrollToPosition
generateDefaultLayoutParams() • abstractϝιου • RecyclerViewͷࢠViewʹ͏LayoutParamsΛฦ͢ • RecyclerView.LayoutParams ͰجຊతʹOK • ΧελϜLayoutParamsΛ͏߹ɺҎԼͷϝιουΛ
override͢Δඞཁ͋Γ • checkLayoutParamsɿܕνΣοΫ • generateLayoutParamsɿϨΠΞτxml͔Βinflateͨ͠ ΓɺଞͷLayoutParamsΛίϐʔͨ͠Γ
onLayoutChildren(Recycler, State) • LayoutManagerͷ࠷ॏཁϝιου • ࢠViewͷஔɺεΫϩʔϧʹ͏ViewੜɺViewͷϦ αΠΫϧͳͲΛߦ͏ • ʮRecyclerViewͷྖҬʹʯදࣔ͢Δͯ͢ͷViewͷ ϨΠΞτॲཧΛߦ͏
• ྖҬ֎ͷͷʹ͍ͭͯScrollܥϝιουͰ
canScroll(Horizontally|Vertically)By • boolean canScrollHorizontallyBy() • boolean canScrollVerticallyBy() • ԣํʗॎํʹεΫϩʔϧͰ͖Δ͔Ͳ͏͔ •
ϨΠΞτํʹΑܾͬͯΊΔͱྑ͍
scroll(Horizontally|Vertically)By • int scrollHorizontallyBy(int, Recycler, State) • int scrollVerticallyBy(int, Recycler,
State) • ࢠViewΛԣʗॎʹҠಈ͢ΔྔΛฦ͢ • ৽͘͠ը໘ʹදࣔ͞ΕΔViewΛadd͢Δ • ը໘֎ʹফ͑ͨViewΛRecycle͢Δ
scrollToPosition(int) • RecyclerView#scrollToPosition ͷ࣌ʹݺΕΔ • positionΛηοτͯ͠ϨΠΞτͤ͠OK ※LinearLayoutMangerͷ࣮ @Override public void
scrollToPosition(int position) { mPendingScrollPosition = position; mPendingScrollPositionOffset = INVALID_OFFSET; if (mPendingSavedState != null) { mPendingSavedState.invalidateAnchor(); } requestLayout(); } QPTJUJPOΛηοτͯ͠ ࠶ϨΠΞτ
smoothScrollToPosition(RecyclerView, State, int) • RecyclerView#smoothScrollToPosition ͷ࣌ʹݺΕΔ • smooth scrollingΛαϙʔτ͍ͨ࣌͠ʹ࣮͢Δ •
RecyclerView.SmoothScroller ͷΠϯελϯεΛ࡞Γɺ startSmoothScroll ʹ͢ ※LinearLayoutMangerͷ࣮ @Override public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()); linearSmoothScroller.setTargetPosition(position); startSmoothScroll(linearSmoothScroller); }
4. LayoutManagerΛͭͬͯ͘ΈΑ͏
खॱ 1. RecyclerView.LayoutManagerΛܧঝͨ͠ΫϥεΛ࡞Δ 2. onDefaultLayoutParams Λ࣮͢Δ 3. onLayoutManager Λ࣮͢Δ 4.
ViewͷฒํΛม͑ͯΈΔ 5. εΫϩʔϧͰ͖ΔΑ͏ʹ͢Δ
Demo https://github.com/consomme/DroidKaigi2017Sample
·ͱΊ • දࣔ͢Δ͚ͩͳΒ࣮؆୯ • onLayoutChildren ͷ࣮Λ͢Ε͘͠ͳ͍ • ͔ͦ͜ΒઌΛ࣮͢Δͷ͕͍͠ • εΫϩʔϧͱ͔ɺͦΕʹ͏ViewͷϦαΠΫϧͱ͔ɺϓ
ϦϑΣονͱ͔ɺϓϦϩʔυͱ͔… • ͍͔ʹޮతʹදࣔ͢Δ͔Λಥ͖٧ΊΔͱׂͱপ • શ෦Λཧղ͢ΔͷແཧͳͷͰɺ෦తʹগͣͭ͠ཧղΛ ਐΊΔ΄͏͕͍͍ • RecyclerViewͷιʔείʔυ12,000ߦҎ্͋Γ·͢
ʲॏཁͳͷͰ̎ݴ͍·͢ʳؒืूத https://www.wantedly.com/companies/pixiv
͋Γ͕ͱ͏͍͟͝·ͨ͠