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

LayoutManagerをつくろう

consomme
March 10, 2017

 LayoutManagerをつくろう

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

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ߦҎ্͋Γ·͢