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

MDCの内部実装から学ぶ
表現力の高いViewの作り方

HiroYUKI Seto
February 17, 2020

 MDCの内部実装から学ぶ
表現力の高いViewの作り方

20/02/20
DroidKaigi2020 Day1

2020/08/27
DroidKaigi2020 Lite Day1

HiroYUKI Seto

February 17, 2020
Tweet

More Decks by HiroYUKI Seto

Other Decks in Technology

Transcript

  1. X © DMM.com w ੉ށ༏೭ !TFUP@IJ  w ߹ಉձࣾ%..DPN$50ࣨࣄۀࢧԉνʔϜ w

    ిࢠॻ੶ࣄۀ෦ͷ"OESPJEΞϓϦ։ൃͷࢧԉத w .BUFSJBM%FTJHOେ޷͖ w ޷͖ͳ"1*͸$BOWBTTBWFͱ7JFX(SPVQMBZPVU ࣗݾ঺հ
  2. X © DMM.com දݱྗͷߴ͍7JFXΛ࡞ΕΔΑ͏ʹͳΔ w 7JFXͷ಺෦࣮૷Λ஌ΓϕετϓϥΫςΟεΛ஌Δ w ඳըɺϨΠΞ΢τ w Ξχϝʔγϣϯ

    w 7JFXͷτϥϒϧʹରॲͰ͖ΔྗΛ਎ʹ͚ͭΔ w 7JFXΛਖ਼͘͠࢖ͬͯτϥϒϧΛݮΒ͢ w ࣗ෼ͷҙਤ͠ͳ͍ಈ࡞ͷݪҼΛௐࠪͰ͖Δ ηογϣϯͷ໨ࢦ͢΋ͷ
  3. X © DMM.com w GQTΛҡ࣋͢Δ͜ͱ͸ͱͯ΋ॏཁ w ࣮૷Λ޻෉͢Δඞཁ͕͋Δ w ϨΠΞ΢τॲཧ͸ॏ͍ w

    ඳը͸ॏ͘ͳ͍ w NFBTVSFͰͷ7JFXͷαΠζΛܭࢉ͢ΔͨΊ w ෳࡶͳߏ଄ͩͱߋʹॏ͍ w Ξχϝʔγϣϯʹ͸5SBOTJUJPOͱ"OJNBUPS͕ෆՄܽ w 5SBOTJUJPOͰͭͷঢ়ଶؒΛ݁Ϳ w 7BMVF"OJNBUPS 0CKFDU"OJNBUPS FUDʜ 7JFXͷ࣮૷Ͱେ੾ͳ͜ͱ
  4. X © DMM.com ηογϣϯͷྲྀΕ w .BUFSJBM4IBQF%SBXBCMF w %SBXBCMFͷجૅ w .BUFSJBM4IBQF%SBXBCMFͷ࢓૊Έͱ࢖͍ํ

    w 4IBEPXͷ࣮૷ w &YUFOEFE'"#ͱ#PUUPN"QQ#BS w จࣈαΠζΛม͑ΔΞχϝʔγϣϯͷ࣮૷ w #PUUPN/BWJHBUJPOͱ5FYU'JFME w 7JFXͷαΠζΛม͑Δ࣮૷ w &YUFOEFE'"#ͱ$IJQT
  5. X © DMM.com w .%$ʹؚ·ΕΔίϯϙʔωϯτ w 7JFXͷ#BDLHSPVOEͱͯ͠࢖͏ w ֯ΛΧελϚΠζͰ͖Δ w

    ݟͨ໨ɺαΠζ w ྠֲͷΧελϚΠζ͕Ͱ͖Δ w ྠֲͷਤܗΛมߋͰ͖Δ w ԑऔΓʹͰ͖Δ w 4IBEPXͷඳը͕Ͱ͖Δ w 'SBNFXPSLͷ7JFXΑΓ΋ෳࡶͳ4IBEPX΋Մೳ .BUFSJBM4IBQF%SBXBCMFͱ͸
  6. X © DMM.com .BUFSJBM4IBQF%SBXBCMFͷ4IBEPX 'SBNFXPSLͷ7JFX .BUFSJBM4IBQF%SBXBCMF ԁɺପԁ ˓ ˓ ۣܗɺؙۣ֯ܗ

    ˓ ˓ ϕδΤۂઢؚ͕·ΕΔͱʷ ತਤܗ ˓ ˓ ϕδΤۂઢؚ͕·ΕΔͱʷ ඇತਤܗ ʷ "1*͔Β˓ ˓ ϕδΤۂઢؚ͕·ΕΔͱʷ
  7. X © DMM.com w 4UBUF-JTU%SBXBCMFͱ͸ผ෺ w %SBXBCMFͷঢ়ଶΛอ࣋͢Δ w ΞϧϑΝ஋ɺ$PMPS4UBUF-JTUɺ5JOU w

    ࣗ࡞%SBXBCMFͰ͸$POTUBOU4UBUF΋ࣗ࡞͢Δ͜ͱ͕ଟ͍ • MaterialShapeDrawableState extends ConstantState w $POTUBOU4UBUFOFX%SBXBCMF Ͱ࡞੒ͨ͠%SBXBCMFؒͰڞ༗͞ΕΔ w 3FTPVSDFTHFU%SBXBCMFͷ಺෦Ͱ࢖ΘΕΔ w NVUBUF Ͱঢ়ଶ͕ಠཱ͢Δ %SBXBCMF$POTUBOU4UBUF
  8. X © DMM.com w $BOWBTʹͲͷ͘Β͍ͷαΠζͰඳը͢Δ͔ w TFU#PVOET w 7JFXଆ͸JOUSJOTJD8JEUI)FJHIUΛࢀߟʹ͢Δ w

    #JUNBQ%SBXBCMF͸ը૾ͷղ૾౓ w 7FDUPS%SBXBCMF͸xmlͷandroid:widthandroid:height • σϑΥϧτ஋͸ -1 w JOUSJOTJDͷ஋ͳ͠ %SBXBCMFTFU#PVOET
  9. X © DMM.com • MaterialShapeDrawableState • extends ConstantState w ShapeAppearanceModel

    w ͲΜͳܗঢ়ͷ%SBXBCMF͔ͷ৘ใ • ShapePathProvider w ShapeAppearanceModelΛPathʹม׵͢Δ ొ৔ਓ෺
  10. X © DMM.com w ܗঢ়ͷ஋Ϋϥε w 4IBQFBCMF*NBHF7JFXͳͲͰ΋࢖ΘΕΔ w ลͱ֯ͷΧελϚΠζ͕Ͱ͖Δ w

    TFU"MM$PSOFS4J[FT TFU5PQ-FGU$PSOFS4J[F FUD w TFU"MM$PSOFST TFU5PQ-FGU$PSOFS FUD w TFU"MM&EHFT TFU5PQ&EHF FUD 4IBQF"QQFBSBODF.PEFM
  11. X © DMM.com 4IBQF"QQFBSBODF.PEFM ShapeAppearanceModel CornerTreatment topLeftCorner topRightCorner bottomRightCorner bottomLeftCorner

    CornerSize topLeftCornerSize topRightCornerSize bottomRightCornerSize bottomLeftCornerSize EdgeTreatment topEdge rightEdge bottomEdge leftEdge
  12. X © DMM.com MaterialShapeDrawable.draw ඳըͷ࢓૊Έ MaterialShapeDrawable .calculateShapePath / calculatePath ShapePathProvider

    .calculatePath MaterialShapeDrawable .drawFillShape / drawStrokeShape Canvas.drawPath / drawRoundRect ShapeAppearanceModel Path Path Path
  13. X © DMM.com MaterialShapeDrawable.setInterpolation( float interpolation) EdgeTreatment.getEdgePath( float length, float

    center, float interpolation, @NonNull ShapePath shapePath) CornerTreatment.getCornerPath( @NonNull ShapePath shapePath, float angle, float interpolation, @NonNull RectF bounds, @NonNull CornerSize size) #PUUPN"QQ#BS
  14. X © DMM.com override fun getEdgePath( length: Float, center: Float,

    interpolation: Float, shapePath: ShapePath ) { shapePath.lineTo(arrowRight, 0f) shapePath.lineTo(arrowRight, -arrowHeight) shapePath.lineTo(arrowRight + arrowHeight, 0f) shapePath.lineTo(length, 0f) } &EHF5SFBUNFOUΛ࣮૷͢Δ
  15. X © DMM.com val background = MaterialShapeDrawable(model).apply { fillColor =

    ColorStateList.valueOf(Color.WHITE) this.elevation = elevation setPadding(padding, padding, padding, padding) } speechBalloon.background = background .BUFSJBM4IBQF%SBXBCMFΛ࡞Δ
  16. X © DMM.com w ԁܗͱۣܗϕʔεͰͳ͍ਤܗ͸දݱ͕೉͍͠ w ࡾ֯ܗɺ੕ܗͳͲ w 4IBQF"QQFBSBODF.PEFMͷ੍ݶ w

    ֎ଆʹ͸Έग़͢ਤܗͷ৔߹ w ਌7JFXͷDMJQ$IJMESFOGBMTFΛ͢Δ w *OTFU%SBXBCMFͰғΉ w 4IBEPXΛΑ͘ݟΔͱૈ͍ w ඇತਤܗͰ͸஫ҙ ஫ҙ఺
  17. X © DMM.com w 7JFXͷഎܠ༻%SBXBCMF w ࣗ༝౓ͷߴ͍σβΠϯΛදݱͰ͖Δ w 4IBQF"QQFBSBODF.PEFMΛ࢖͏ w

    ԁܗͱۣܗϕʔεͰͳ͍ਤܗ͸දݱ͕೉͍͠ w 4IBEPXΛඳըͰ͖Δ w "1*ະຬͰ͸'SBNFXPSLͷ7JFXΑΓ΋ෳࡶͳ4IBEPXΛඳը .BUFSJBM4IBQF%SBXBCMF·ͱΊ
  18. X © DMM.com w 7JFXͷྠֲ৘ใΛఏڙ͢ΔΫϥε "1*d  w HFU0VUMJOFͰྠֲઃఆ w

    4IBEPXͷܭࢉͳͲʹ࢖ΘΕΔ w ͍͔࣮ͭ͘૷ࡁΈΠϯελϯε͕͋Δ • BACKGROUND • BOUNDS • PADDED_BOUNDS • 7JFXͷॳظ஋͸BACKGROUND • View.background.getOutline 7JFX0VUMJOF1SPWJEFS
  19. X © DMM.com public void getOutline(@NonNull Outline outline) { if

    (drawableState.shadowCompatMode == SHADOW_COMPAT_MODE_ALWAYS) { // Don't draw the native shadow if we're always rendering with compat shadow. return; } if (isRoundRect()) { float radius = getTopLeftCornerResolvedSize(); outline.setRoundRect(getBounds(), radius); return; } calculatePath(getBoundsAsRectF(), path); if (path.isConvex() || Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { outline.setConvexPath(path); } } .BUFSJBM4IBQF%SBXBCMFHFU0VUMJOF
  20. X © DMM.com public void getOutline(@NonNull Outline outline) { if

    (drawableState.shadowCompatMode == SHADOW_COMPAT_MODE_ALWAYS) { // Don't draw the native shadow if we're always rendering with compat shadow. return; } if (isRoundRect()) { float radius = getTopLeftCornerResolvedSize(); outline.setRoundRect(getBounds(), radius); return; } calculatePath(getBoundsAsRectF(), path); if (path.isConvex() || Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { outline.setConvexPath(path); } } .BUFSJBM4IBQF%SBXBCMFHFU0VUMJOF .BUFSJBM4IBQF%SBXBCMFͰTIBEPXΛඳը͢Δઃఆ ˠ0VUMJOFΛઃఆ͠ͳ͍ 'SBNFXPSLଆͷTIBEPXͳ͠
  21. X © DMM.com public void getOutline(@NonNull Outline outline) { if

    (drawableState.shadowCompatMode == SHADOW_COMPAT_MODE_ALWAYS) { // Don't draw the native shadow if we're always rendering with compat shadow. return; } if (isRoundRect()) { float radius = getTopLeftCornerResolvedSize(); outline.setRoundRect(getBounds(), radius); return; } calculatePath(getBoundsAsRectF(), path); if (path.isConvex() || Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { outline.setConvexPath(path); } } .BUFSJBM4IBQF%SBXBCMFHFU0VUMJOF %SBXBCMF͕3PVOE3FDU ˠ0VUMJOFTFU3PVOE3FDU %SBXBCMF͕3PVOE3FDU ˠ0VUMJOFTFU3PVOE3FDU
  22. X © DMM.com public void getOutline(@NonNull Outline outline) { if

    (drawableState.shadowCompatMode == SHADOW_COMPAT_MODE_ALWAYS) { // Don't draw the native shadow if we're always rendering with compat shadow. return; } if (isRoundRect()) { float radius = getTopLeftCornerResolvedSize(); outline.setRoundRect(getBounds(), radius); return; } calculatePath(getBoundsAsRectF(), path); if (path.isConvex() || Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { outline.setConvexPath(path); } } .BUFSJBM4IBQF%SBXBCMFHFU0VUMJOF %SBXBCMFͷྠֲͷ1BUI͕ತਤܗ Path.isConvex()  ·ͨ͸"1*Ҏ্ ˠ0VUMJOFTFU$POWFY1BUI
  23. X © DMM.com public void getOutline(@NonNull Outline outline) { if

    (drawableState.shadowCompatMode == SHADOW_COMPAT_MODE_ALWAYS) { // Don't draw the native shadow if we're always rendering with compat shadow. return; } if (isRoundRect()) { float radius = getTopLeftCornerResolvedSize(); outline.setRoundRect(getBounds(), radius); return; } calculatePath(getBoundsAsRectF(), path); if (path.isConvex() || Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { outline.setConvexPath(path); } } .BUFSJBM4IBQF%SBXBCMFHFU0VUMJOF ͦΕҎ֎ ˠ0VUMJOFΛઃఆ͠ͳ͍ 'SBNFXPSLଆͷTIBEPXͳ͠
  24. X © DMM.com public void getOutline(@NonNull Outline outline) { if

    (drawableState.shadowCompatMode == SHADOW_COMPAT_MODE_ALWAYS) { // Don't draw the native shadow if we're always rendering with compat shadow. return; } if (isRoundRect()) { float radius = getTopLeftCornerResolvedSize(); outline.setRoundRect(getBounds(), radius); return; } calculatePath(getBoundsAsRectF(), path); if (path.isConvex() || Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { outline.setConvexPath(path); } } .BUFSJBM4IBQF%SBXBCMFHFU0VUMJOF %SBXBCMF͕3PVOE3FDU ˠ0VUMJOFTFU3PVOE3FDU %SBXBCMF͕3PVOE3FDU ˠ0VUMJOFTFU3PVOE3FDU
  25. X © DMM.com  .BUFSJBM4IBQF%SBXBCMFͰTIBEPXΛඳը͢Δઃఆ w ˠ0VUMJOFΛઃఆ͠ͳ͍ 'SBNFXPSLଆͷTIBEPXͳ͠  

    %SBXBCMF͕3PVOE3FDU w ˠ0VUMJOFTFU3PVOE3FDU  %SBXBCMFͷྠֲͷ1BUI͕ತਤܗ Path.isConvex()  ·ͨ͸"1*Ҏ্ w ˠ0VUMJOFTFU$POWFY1BUI  ͦΕҎ֎ w ˠ0VUMJOFΛઃఆ͠ͳ͍ 'SBNFXPSLଆͷTIBEPXͳ͠ .BUFSJBM4IBQF%SBXBCMFHFU0VUMJOF
  26. X © DMM.com w 4IBEPXʹࠔ͍ͬͯͳ͍ͳΒؾʹ͠ͳ͍ w 4IBEPXʹࠔͬͨΒ.BUFSJBM4IBQF%SBXBCMFΛࢼ͢ w 04όʔδϣϯ΍ྠֲΛؾʹͤͣTIBEPXΛඳը͢Δ w

    ͨͩ͠.BUFSJBM4IBQF%SBXBCMFͷྠֲͷදݱʹ͸ݶք͕͋Δ w ԁͱۣܗϕʔεͷਤܗ w .BUFSJBM4IBQF%SBXBCMFͰ΋ղܾͰ͖ͳ͍৔߹͸େม w 4IBEPX3FOEFSFSΛࢀߟʹࣗ࡞͢Δ w PSσβΠϯΛม͑Δ ࢖͍෼͚
  27. X © DMM.com w Ξχϝʔγϣϯ༻ͷ஋Λఏڙ͢ΔΫϥε w ࢦఆͨ࣌ؒ͠಺Ͱ͍͍ײ͡ʹ஋ΛมԽͤͯ͘͞ΕΔ w VQEBUF-JTUFOFSͰ஋Λॲཧ͢Δ w

    ඵؒʹճఔ౓஋ݺ͹ΕΔ w ॏ͍ॲཧΛ͠ͳ͍ʂ w *OUFSQPMBUPSΛ࢖ͬͯมԽྔΛมԽͤ͞Δ͜ͱ͕Ͱ͖Δ 7BMVF"OJNBUPS 7BMVF"OJNBUPS
  28. X © DMM.com 7BMVF"OJNBUPS 7BMVF"OJNBUPS ValueAnimator.ofFloat(0f, 100f).apply { duration =

    1000L addUpdateListener { animator -> view.translationX = animator.animatedValue as Float } start() }
  29. X © DMM.com w 7BMVF"OJNBUPSΛܧঝͨ͠Ϋϥε w ࢦఆͨ࣌ؒ͠಺Ͱ೚ҙͷϓϩύςΟΛมԽͤ͞Δ w VQEBUF-JTUFOFS͸ඵؒʹճఔ౓஋͕ߋ৽͞ΕΔ w

    *OUFSQPMBUPSΛ࢖ͬͯมԽྔΛมԽͤ͞Δ͜ͱ͕Ͱ͖Δ w ϓϩύςΟ΁ͷΞΫηε͸ϦϑϨΫγϣϯ 0CKFDU"OJNBUPS
  30. X © DMM.com w 7BMVF"OJNBUPS0CKFDU"OJNBUPS ObjectAnimator.ofFloat(view, “translationX”, 0f, 100f).apply {

    duration = 1000L start() } ValueAnimator.ofFloat(0f, 100f).apply { duration = 1000L addUpdateListener { animator -> view.translationX = animator.animatedValue as Float } start() }
  31. X © DMM.com w JOWBMJEBUF w ϝΠϯεϨου͔Β͔͠ݺ΂ͳ͍ w ͙͢ʹ࠶ඳը͢Δ͜ͱΛཁٻ͢Δ w

    QPTU*OWBMJEBUF w αϒεϨου͔Β΋ݺ΂Δ w )BOEMFSܦ༝Ͱ࠶ඳըΛཁٻ͢Δ w QPTU*OWBMJEBUF0O"OJNBUJPO w αϒεϨου͔Β΋ݺ΂Δ w ࣍ϑϨʔϜͰ࠶ඳը͢ΔΑ͏ʹཁٻ͢Δ ิ଍ɿ7JFX࠶ඳըϝιου࢖͍෼͚
  32. X © DMM.com w ϨΠΞ΢τલޙͷঢ়ଶؒΛ͍͍ײ͡ʹΞχϝʔγϣϯͰ݁Ϳ w Ξχϝʔγϣϯʹ͸"OJNBUPS͕࢖ΘΕΔ͜ͱ͕ଟ͍ w ࢖͍ํ͸؆୯ w

    σϑΥϧτͰ'BEFͱ$IBOHF#PVOET͕ಈ͘ w ҰൠతͳΞχϝʔγϣϯ͸࣮૷ࡁ w 'BEF 4MJEF $IBOHF#PVOET w ࣗ෼Ͱ࣮૷͢Δ͜ͱ΋ग़དྷΔ 5SBOTJUJPO TransitionManager.beginDelayedTransition(viewGroup) view.visibility = View.GONE
  33. X © DMM.com w 7BMVF"OJNBUPS w Ξχϝʔγϣϯ༻ͷ஋Λఏڙ͢Δ w 0CKFDU"OJNBUPS w

    Ξχϝʔγϣϯ༻ʹϓϩύςΟΛมߋ͢Δ w 5SBOTJUJPO w ϨΠΞ΢τલޙͷঢ়ଶΛ͍͍ײ͡ʹΞχϝʔγϣϯͰ݁Ϳ Ξχϝʔγϣϯͷલఏ஌ࣝ
  34. X © DMM.com w "DUJWF༻ͱ*OBDUJWF༻ͷͭͷ5FYU7JFX͕͋Δ w 5SBOTJUJPOͰঢ়ଶΛܨ͙ w 5FYU4DBMFFYUFOET5SBOTJUJPO w

    7BMVF"OJNBUPSͰ஋ΛมԽ w αΠζมߋʹ࢖͏ͷ͸TDBMF9ͱTDBMF: w Ξχϝʔγϣϯதʹ࠶ϨΠΞ΢τΛൃੜͤ͞ͳ͍ͨΊ w TFU4DBMF9ͱTFU4DBMF:͸࠶ϨΠΞ΢τ͕ൃੜ͠ͳ͍ w TFU5FYU4J[F͸࠶ϨΠΞ΢τ͕ൃੜ͢Δ ࣮૷ͷ࢓૊Έ
  35. X © DMM.com w &EJU5FYUͷIJOU͸࢖Θͳ͍ w 5FYU*OQVU-BZPVU͕$BOWBTʹIJOUΛඳը w $PMMBQTJOH5FYU)FMQFS w

    7BMVF"OJNBUPS $BOWBTESBX5FYU w ঃʑʹςΩετΛখ͘͞ඳը͍ͯ͠Δ w 1BJOUTFU5FYU4J[F w "1*ҎԼͰ͸ύϑΥʔϚϯεͷؔ܎Ͱ#JUNBQΛॖখ w $PMMBQTJOH5PPMCBS-BZPVU΋$PMMBQTJOH5FYU)FMQFSΛ࢖͏ ࣮૷ͷ࢓૊Έ
  36. X © DMM.com w &YUFOEFE'"#FYUFOE TISJOL  w ಺෦తʹ͸0CKFDU"OJNBUPS w

    MBZPVU1BSBNTXJEUIΛมߋ ຖճSFRVFTU-BZPVU  w ॏ͍ w 7JFX(SPVQͰͳ͍ͷͰ5SBOTJUJPO͸࢖͑ͳ͍ w ࠶ϨΠΞ΢τҎ֎͸Ξχϝʔγϣϯ͢Δํ๏͕ͳ͍ w ঢ়ଶͷࠩ෼͕େ͖͍ͷͰΞχϝʔγϣϯ͠ͳ͍ͱ఻ΘΒͳ͍ w ༨ஊɿ.PUJPO4USBUFHZपΓ͸ಡΈԠ͑ͷ͋Δίʔυʂ Ξχϝʔγϣϯ෇͖αΠζมߋ
  37. X © DMM.com w $IJQ͸3FDZDMFS7JFXͳͲͰΑ͘࢖ΘΕΔ w Ξχϝʔγϣϯ࣌ʹ࠶ϨΠΞ΢τΛֻ͚Δ 3FDZDMFS7JFXͷཁૉͷ࠶ϨΠΞ΢τ w ίετ͕ඇৗʹߴ͍

    w ࠩ෼͕গͳ͍ͷͰΞχϝʔγϣϯ͠ͳͯ͘΋఻ΘΔ w Ξχϝʔγϣϯ͸ઈରͷਖ਼ղͰ͸ͳ͍ Ξχϝʔγϣϯͤͨ͞ํ͕ྑ͍ʁ
  38. X © DMM.com w 5SBOTJUJPOͷ$IBOHF#PVOET w ࠷΋Ұൠతͳํ๏ w -JTUͷཁૉʹͳΓ͏Δ7JFX w

    SFRVFTU-BZPVUΛ͋·Γݺ͹ͳ͍ w 7JTJCJMJUZͷ੾Γସ͚͑ͩͰྑ͍͔΋ w ߴ͍දݱྗ͕ඞཁͳ7JFX w SFRVFTU-BZPVUΛͨ͘͞ΜݺͿ͜ͱ΋ߟ͑Δ w ϑϨʔϜམͪͷՄೳੑΛߟ͓͑ͯ͘ w ࢖͍෼͚
  39. X © DMM.com දݱྗͷߴ͍7JFXΛ࡞ΕΔΑ͏ʹͳΔ w 7JFXͷ಺෦࣮૷Λ஌ΓɺϕετϓϥΫςΟεΛ஌Δ w ඳըɺϨΠΞ΢τ w Ξχϝʔγϣϯ

    w 7JFXͷτϥϒϧʹରॲͰ͖ΔྗΛ਎ʹ͚ͭΔ w 7JFXΛਖ਼͘͠࢖ͬͯτϥϒϧΛݮΒ͢ w ࣗ෼ͷҙਤ͠ͳ͍ಈ࡞ͷݪҼΛௐࠪͰ͖Δ ηογϣϯͷ໨ࢦ͢΋ͷ
  40. X © DMM.com w GQTΛҡ࣋͢Δ͜ͱ͸ͱͯ΋ॏཁ w ࣮૷Λ޻෉͢Δඞཁ͕͋Δ w ϨΠΞ΢τॲཧ͸ॏ͍ w

    ඳը͸ॏ͘ͳ͍ w NFBTVSFͰͷ7JFXͷαΠζΛܭࢉ͢ΔͨΊ w ෳࡶͳߏ଄ͩͱߋʹॏ͍ w Ξχϝʔγϣϯʹ͸5SBOTJUJPOͱ"OJNBUPS͕ෆՄܽ w 5SBOTJUJPOͰͭͷঢ়ଶؒΛ݁Ϳ w 7BMVF"OJNBUPS 0CKFDU"OJNBUPS FUDʜ 7JFXͷ࣮૷Ͱେ੾ͳ͜ͱ
  41. X © DMM.com w .BUFSJBM%FTJHO w IUUQTNBUFSJBMJPEFTJHO w .BUFSJBM$PNQPOFOUTGPS"OESPJE w

    IUUQTHJUIVCDPNNBUFSJBMDPNQPOFOUTNBUFSJBMDPNQPOFOUT BOESPJE w αϯϓϧ w IUUQTHJUIVCDPNIJSPZVLJTFUPESPJELBJHJTBNQMF ࢀߟ63-
  42. ׬