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

LayoutManagerをつくろう

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

 LayoutManagerをつくろう

DroidKaigi 2017 にて発表した資料です。

Avatar for consomme

consomme

March 10, 2017
Tweet

More Decks by consomme

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ • ͜ΜͦΊ / ࢁ࡚ ਖ਼ (Tadashi Yamazaki) • ϐΫγϒגࣜձࣾɹAndroidΞϓϦΤϯδχΞ

    • Twitter : @consomme72 • Github : consomme • FGO : 071,679,396 • Nintendo Switch : SW-3116-2713-1429
  2. ஫ҙࣄ߲ • Support Library 25.2.0 લఏͷ͓࿩Ͱ͢ • ࠓޙόʔδϣϯΞοϓͯ͠શવҧ͏࣮૷ʹมΘΔՄೳੑ ͸େ͍ʹ͋Γ·͢ •

    GoogleઌੜΛ৴͡Α • ͍Ζ͍Ζઆ໌͕ෆ଍͍ͯͨ͠Γؒҧ͍ͬͯΔՄೳੑ΋ ͋Γ·͢ • RecyclerViewͷίʔυશ෦ݟΔͷͱ͔ແཧ
  3. RecyclerView is Կ • A flexible view for providing a

    limited window into a large data set. • ڊେͳσʔληοτΛݶΒΕͨྖҬ಺ʹฒ΂ΔͨΊͷ View • ListView΍GridViewͰ͸Ͱ͖ͳ͔ͬͨॲཧ͕Մೳ • σʔλͷछྨͰViewΛม͑Δͱ͔͕؆୯ • Ξχϝʔγϣϯͱ͔΋ࣗಈͰ΍ͬͯ͘ΕΔ • ͦͷ͔ΘΓࣗલͰ͍Ζ͍Ζ༻ҙ͠ͳ͍ͱ͍͚ͳ͍ • ۠੾Γઢͱ͔λοϓΠϕϯτͱ͔
  4. LayoutManager is Կ • RecyclerViewʹ͓͍ͯɺࢠViewΛͲͷΑ͏ʹ഑ஔ͢Δ ͔Λܾఆ͢Δ΋ͷ • ࢠViewͷαΠζܭࢉɺฒ΂ํɺεΫϩʔϧʹΑΔView ͷϦαΠΫϧͳͲΛ੍ޚ͍ͯ͠Δ •

    LayoutManagerΛมߋ͢Ε͹ɺRecyclerView΍Adapter ͷมߋΛ͢Δ͜ͱͳ͘ϨΠΞ΢τͷมߋ͕Մೳ • ListView΍GridViewͰ͸ෆՄೳ
  5. 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͢Δ
  6. 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Ληοτ ϨΠΞ΢τΛ࠶ඳը
  7. RecyclerViewʹ͓͚ΔࢠViewͷαΠζଌఆ • Support Library 23.2.0 ΑΓɺRecyclerViewʹ WRAP_CONTENT ͕࢖͑ΔΑ͏ʹͳͬͨ • WRAP_CONTENT

    Λ࢖͏ʹ͸ɺLayoutManagerଆͰ setAutoMeasuredEnabled(true) Λࢦఆ͢Δඞཁ͋Γ • ٯʹݴ͑͹ɺ͜Ε͕trueʹͳ͍ͬͯͳ͍৔߹͸ WRAP_CONTENT ͸࢖͑ͳ͍ʢϨΠΞ΢τ่͕Ε Δʣ
  8. setAutoMeasureEnabled ͷ؆୯ͳઆ໌ • RecyclerView΍LayoutManager͕ࣗಈͰViewͷαΠζΛܭࢉ͢Δ͔Ͳ ͏͔ΛܾΊΔ • trueΛηοτͨ͠৔߹ • ࣗಈͰViewͷαΠζܭࢉΛߦ͏ •

    WRAP_CONTENT Λ༗ޮʹ͚ͨ͠Ε͹trueʹ͢Δ • falseΛηοτͨ͠৔߹ • ViewͷαΠζܭࢉ͸ RecyclerView#onMeasure ʹॲཧΛॻ͘ • ॻ͔ͳ͍ͱView͕දࣔ͞Εͳ͍ • ΧελϚΠζͨ͠ܭࢉϩδοΫΛ࢖͍͍ͨ৔߹ʹ࢖͏ • σϑΥϧτ஋͸falseʹͳ͍ͬͯΔͷͰ஫ҙ
  9. LayoutManagerͷओͳϝιου • abstractϝιου • generateDefaultLayoutParams • abstract͡Όͳ͍͚Ͳ࣮૷ඞਢͳϝιου • onLayoutChildren •

    canScrollHorizontally / canScrollVertically • scrollHorizontallyBy / scrollVerticallyBy • ͦͷଞॏཁϝιου • scrollToPosition • smoothScrollToPosition
  10. generateDefaultLayoutParams() • abstractϝιου • RecyclerViewͷࢠViewʹ࢖͏LayoutParamsΛฦ͢ • RecyclerView.LayoutParams Ͱجຊతʹ͸OK • ΧελϜLayoutParamsΛ࢖͏৔߹ɺҎԼͷϝιουΛ

    override͢Δඞཁ͋Γ • checkLayoutParamsɿܕνΣοΫ • generateLayoutParamsɿϨΠΞ΢τxml͔Βinflateͨ͠ ΓɺଞͷLayoutParamsΛίϐʔͨ͠Γ
  11. scroll(Horizontally|Vertically)By • int scrollHorizontallyBy(int, Recycler, State) • int scrollVerticallyBy(int, Recycler,

    State) • ࢠViewΛԣʗॎʹҠಈ͢ΔྔΛฦ͢ • ৽͘͠ը໘಺ʹදࣔ͞ΕΔViewΛadd͢Δ • ը໘֎ʹফ͑ͨViewΛRecycle͢Δ
  12. 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Ληοτͯ͠ ࠶౓ϨΠΞ΢τ
  13. 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);
 }
  14. ·ͱΊ • දࣔ͢Δ͚ͩͳΒ࣮͸؆୯ • onLayoutChildren ͷ࣮૷Λ޻෉͢Ε͹೉͘͠ͳ͍ • ͔ͦ͜ΒઌΛ࣮૷͢Δͷ͕೉͍͠ • εΫϩʔϧͱ͔ɺͦΕʹ൐͏ViewͷϦαΠΫϧͱ͔ɺϓ

    ϦϑΣονͱ͔ɺϓϦϩʔυͱ͔… • ͍͔ʹޮ཰తʹදࣔ͢Δ͔Λಥ͖٧ΊΔͱׂͱপ • શ෦Λཧղ͢Δͷ͸ແཧͳͷͰɺ෦෼తʹগͣͭ͠ཧղΛ ਐΊΔ΄͏͕͍͍ • RecyclerViewͷιʔείʔυ͸12,000ߦҎ্͋Γ·͢