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

実例で理解する Material Design Animation

90ec81078e4fd2b905f8ef0776887afa?s=47 Ryo Sakaguchi
February 08, 2018

実例で理解する Material Design Animation

DroidKaigi 2018 2/8 Room2

90ec81078e4fd2b905f8ef0776887afa?s=128

Ryo Sakaguchi

February 08, 2018
Tweet

More Decks by Ryo Sakaguchi

Other Decks in Programming

Transcript

  1. 2018.2.8 ࣮ྫͰཧղ͢Δ Material Design Animation DroidKaigi 2018 Room2 Feb 8th,

    2018 Ryo Sakaguchi (wakwak3125)
  2. 2018.2.8 Ryo Sakaguchi @wakwak3125 • Wantedly, Inc • Android application

    developer • Wantedly People • Music, Guitar, UI/UX About me
  3. 2018.2.8 Ryo Sakaguchi @wakwak3125 • Wantedly, Inc • Android application

    developer • Wantedly People • Music, Guitar, UI/UX About me
  4. 2018.2.8 Wantedly People

  5. 2018.2.8 Wantedly People • ໊ࢗ؅ཧΞϓϦ • ػցֶशΛ࢖༻͍ͯ͠Δ • ಡΈऔ໊ͬͨࢗ΍ɺࣗ෼ͷ৘ใΛݩ ʹʮ࿩୊ʯΛఏڙ͢Δ

    • ؾ໊͍͍࣋ͪࢗࡱӨମݧ
  6. 2018.2.8 Wantedly People • ໊ࢗ؅ཧΞϓϦ • ػցֶशΛ࢖༻͍ͯ͠Δ • ಡΈऔ໊ͬͨࢗ΍ɺࣗ෼ͷ৘ใΛݩ ʹʮ࿩୊ʯΛఏڙ͢Δ

    • ؾ໊͍͍࣋ͪࢗࡱӨମݧ
  7. 2018.2.8 Agenda

  8. 2018.2.8 Agenda • ʮ࿩୊ʯػೳͷΞχϝʔγϣϯͷ঺հ • ࣮૷ͷղઆ • Ξχϝʔγϣϯ࣮૷ͷצॴ • ΞχϝʔγϣϯͷDebug

  9. 2018.2.8 ʮ࿩୊ʯػೳͷΞχϝʔγϣϯ঺հ

  10. 2018.2.8 Article ࿩୊ͷهࣄΛදࣔ͢Δը໘ • ഑৴͞ΕΔ࿩୊Λදࣔ͢Δը໘ • Ϣʔβʔʹରͯ͠஫໨ͯ͠΄͍͠ʮը૾ʯ Λ࣠ʹΞχϝʔγϣϯ͢Δɻ • RecyclerViewʹΧʔυܕͷΞΠςϜΛฒ

    ΂ɺͦΕ͕Expand͢ΔΠϝʔδ • ΧʔυഎܠˠΧόʔΠϝʔδ • هࣄͷ֓ཁ/λΠτϧͷίϯςΩετ Λڞ༗Ͱ͖Δ ʮ࿩୊ʯػೳͷΞχϝʔγϣϯ঺հ Article
  11. 2018.2.8 Graphic contents ΠϯϑΥάϥϑΟοΫ • ΠϯϑΥάϥϑΟοΫ͕ϝΠϯͷهࣄΛ දࣔ͢Δ • ίϯςϯπࣗମ͸AfterEffectsΛ࢖༻͠ ͯ࡞੒͠ɺbodymovinΛ࢖༻ͯ͠

    WebViewͰ࠶ੜ͍ͯ͠Δ • Χʔυͷഎܠը૾͕શ໘ʹ޿͕͍ͬͯ͘ • Χʔυˠهࣄৄࡉ΁ͷભҠͰੈք؍ ΛଛͳΘͳ͍ ʮ࿩୊ʯػೳͷΞχϝʔγϣϯ঺հ Graphic contents
  12. 2018.2.8 Timeline هࣄ͕දࣔ͞ΕΔTimeline • هࣄΛҰཡͰදࣔ͢ΔRecyclerView • Χʔυ͕എܠը૾Λ࣋ͭλΠϓͱ࣋ͨ ͳ͍λΠϓ͕͋Δ • എܠը૾Λ࣋ͭλΠϓͷ΋ͷͷ৔߹͸ɺ

    Timelineͷഎܠશମʹϒϥʔ͕͔͔ͬ ͨ΋ͷ͕هࣄͷग़ݱͱڞʹΫϩεϑΣʔ υ͢Δ • ࠓճϝΠϯͰ࿩Λ͢Δͭ΋Γͷɺ SharedElementTransitionͱ͸ҧ͏͚ ͲɺҰԠ঺հ ʮ࿩୊ʯػೳͷΞχϝʔγϣϯ঺հ Timeline
  13. 2018.2.8 ΞχϝʔγϣϯͬͯͳΜͰඞཁͳͷʁ

  14. 2018.2.8 ͔͍͍͔ͬ͜Β

  15. 2018.2.8 ͔͍͍͔ͬ͜Βʁ ͚ͩ͡Όͳ͍Ͱ͢ • ΞχϝʔγϣϯʹΑͬͯɺϢʔβʔʹ ஫໨ͯ͠΄͍͠΋ͷΛΞϐʔϧͰ͖Δ • ࢖͍ͬͯͯɺಥવίϯςϯπ͕ೖΕସ Θͬͨ෩ʹײͯ͡͠·͏Ϣʔβʔ΋ډ Δ͸ͣɻ

    • ΍Βͳ͍ΑΓ͸΍ͬͨ΄͏͕ઈରྑ͍ • ΍Γ͗͢͸ྑ͘ͳ͍ɻ͚Ͳɺ·ͣ ͸࡞͔ͬͯΒ࡟͍ͬͯ͘ͷ͕େࣄ • ΋ͪΖΜ͔͍͍ͬͬͯ͜΋ͷ͋Δʂ ΞχϝʔγϣϯͬͯͳΜͰඞཁͳͷʁ
  16. 2018.2.8 ࣮૷ͷղઆ

  17. 2018.2.8 ࣮૷ͷղઆ • Shared Element Transitionͷجຊͷ ͓͞Β͍ • ֤ػೳ(Article/Graphic contents)

    ʹґଘ͠ͳ͍෦෼ͷڞ௨࣮૷ͷ࿩ • ֤ػೳຖʹߦ͍ͬͯΔಛผͳ෦෼ͷ࿩ • Article • Graphic content
  18. 2018.2.8 ·ͣ͸جຊͷ͓͞Β͍

  19. 2018.2.8 Transition Name 1/3 ڞ༗͍ͨ͠Viewʹ໊લΛ͚ͭΔ ·ͣ͸جຊͷ͓͞Β͍ Shared Element Transition public

    class MainActivity extends AppCompatActivity { ActivityMainBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView( this, R.layout.activity_main ); binding.button.setOnClickListener(v -> goToNextActivity()); } void goToNextActivity() { Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation( this, /*ભҠݩͷActivity*/ binding.imageView, /*ભҠݩͱભҠઌͰڞ༗͍ͨ͠View*/
  20. 2018.2.8 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding =

    DataBindingUtil.setContentView( this, R.layout.activity_main ); binding.button.setOnClickListener(v -> goToNextActivity()); } Transition Name 2/3 Transitionʹඞཁͳ৘ใΛBundleʹ٧Ίͯ౉͢ ·ͣ͸جຊͷ͓͞Β͍ Shared Element Transition void goToNextActivity() { Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation( this, /*ભҠݩͷActivity*/ binding.imageView, /*ભҠݩͱભҠઌͰڞ༗͍ͨ͠View*/ "transition:image" /*ڞ༗͍ͨ͠ViewͷTransition Name*/ ).toBundle(); ActivityCompat.startActivity( this, new Intent(this, NextActivity.class), bundle); }
  21. 2018.2.8 Transition Name 3/3 ભҠઌͷActivityͷڞ༗͍ͨ͠ViewʹTransition NameΛηοτ͢Δ ·ͣ͸جຊͷ͓͞Β͍ Shared Element Transition

    this, /*ભҠݩͷActivity*/ binding.imageView, /*ભҠݩͱભҠઌͰڞ༗͍ͨ͠View*/ "transition:image" /*ڞ༗͍ͨ͠ViewͷTransition Name*/ ).toBundle(); ActivityCompat.startActivity( this, new Intent(this, NextActivity.class), bundle); } public class NextActivity extends AppCompatActivity { ActivityNextBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_next); binding.imageView.setTransitionName("transition:image"); } }
  22. 2018.2.8

  23. 2018.2.8 Default animation theme_material.xmlͰ
 σϑΥϧτͰҎԼͷΞχϝʔγϣϯ͕ηοτ͞Ε͍ͯΔ ·ͣ͸جຊͷ͓͞Β͍ Shared Element Transition <transitionSet

    xmlns:android="http://schemas.android.com/apk/res/android"> <changeBounds/> <changeTransform/> <changeClipBounds/> <changeImageTransform/> </transitionSet> move.xml
  24. 2018.2.8 Postpone Transition Transition animationΛ೚ҙͷλΠϛϯάͰ։࢝Ͱ͖Δ ·ͣ͸جຊͷ͓͞Β͍ Shared Element Transition public

    class NextActivity extends AppCompatActivity { static final Handler sHandler = new Handler(Looper.getMainLooper()); ActivityNextBinding binding; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = DataBindingUtil.setContentView(this, R.layout.activity_next); binding.imageView.setTransitionName("transition:image"); ActivityCompat.postponeEnterTransition(this); sHandler.postDelayed(() -> ActivityCompat.startPostponedEnterTransition(this), 1000 ); } }
  25. 2018.2.8 ࣮૷ͷղઆ Wantedly PeopleͰ࢖͍ͬͯΔShared Element Transitionͷڞ௨ͳ෦෼

  26. 2018.2.8 ࣮૷ͷղઆ ڞ௨ͷ෦෼ .BJO"DUJWJUZ

  27. 2018.2.8 ࣮૷ͷղઆ ڞ௨ͷ෦෼ .BJO"DUJWJUZ 5JNFMJOF'SBHNFOU

  28. 2018.2.8 ࣮૷ͷղઆ ڞ௨ͷ෦෼ .BJO"DUJWJUZ 5JNFMJOF'SBHNFOU 1PTU"SUJDMF"DUJWJZ

  29. 2018.2.8 ࣮૷ͷղઆ ڞ௨ͷ෦෼ .BJO"DUJWJUZ 5JNFMJOF'SBHNFOU 1PTU"SUJDMF"DUJWJZ 1PTU"SUJDMF'SBHNFOU

  30. 2018.2.8 ࣮૷ͷղઆ ڞ௨ͷ෦෼ .BJO"DUJWJUZ 5JNFMJOF'SBHNFOU 1PTU"SUJDMF"DUJWJZ 1PTU"SUJDMF'SBHNFOU

  31. 2018.2.8 ͔͜͜ΒϓϩμΫγϣϯίʔυ ͍Ζ͍Ζͳྺ࢙తͳഎܠͰग़དྷ্͕ͬͯ·͢ɻ ࠓ೔͸େ໨ʹݟͯ΄͍͠ʂ Page Title Page Subtitle

  32. 2018.2.8 TimelineFragment ͜ͷFragment͔ΒTransitionΛ։࢝͢Δ /** * @param fragment ભҠݩͷFragment * @param

    postKey هࣄͷKey * @param provider TransitionʹඞཁͳViewΛViewHolder͔Βऔͬͯ͘Δ * adapterΛ࣋ͭ */ public void openPost(BaseFragment fragment, String postKey, PostLogic.ITransitionAdapterProvider provider) { PostArticleFragment nextFragment = PostArticleFragment.newInstance(postKey); TransitionExtra extra = new TransitionExtra.Builder().build(); ࣮૷ͷղઆ ڞ௨ͷ෦෼ // ର৅ͱͳΔViewͱTransition nameͷPairͷListΛ࡞Δ List<Pair<View, String>> pairList = new ArrayList<>(); if (provider != null) { PostLogic.TransitionAdapter adapter = provider.getTransitionAdapter(); // Viewʹରͯ͠ Transition nameΛ༩͍͑ͯ͘
  33. 2018.2.8 TimelineFragment ͜ͷFragment͔ΒTransitionΛ։࢝͢Δ * @param provider TransitionʹඞཁͳViewΛViewHolder͔Βऔͬͯ͘Δ * adapterΛ࣋ͭ */

    public void openPost(BaseFragment fragment, String postKey, PostLogic.ITransitionAdapterProvider provider) { PostArticleFragment nextFragment = PostArticleFragment.newInstance(postKey); TransitionExtra extra = new TransitionExtra.Builder().build(); ࣮૷ͷղઆ ڞ௨ͷ෦෼ // ର৅ͱͳΔViewͱTransition nameͷPairͷListΛ࡞Δ List<Pair<View, String>> pairList = new ArrayList<>(); if (provider != null) { PostLogic.TransitionAdapter adapter = provider.getTransitionAdapter(); // Viewʹରͯ͠ Transition nameΛ༩͍͑ͯ͘ pairList.add(Pair.create( adapter.getCoverImage(), fragment.getString(R.string.transition_image_cover))); // ଞʹ΋View͕͋Ε͹͜͜Ͱηοτ͍ͯ͘͠... } //TransitionExtraʹpairListΛ౉͢ extra.setSharedElementPair(pairList); // BaseFragment͕ը໘ભҠΛߦ͏ؔ਺Λ͍࣋ͬͯΔͷͰͦΕΛݺͼग़͢ fragment.replaceFragment(nextFragment, extra);
  34. 2018.2.8 BaseFragment replaceFragment ࣮૷ͷղઆ ڞ௨ͷ෦෼ public void replaceFragment(@NonNull BaseFragment fragment,

    @Nullable TransitionExtra extra) { // BaseActivity͕listenerΛ࣮૷͍ͯ͠ΔͷͦͪΒʹϦϨʔ͢Δ getListener().replaceFragment(fragment, extra); }
  35. 2018.2.8 BaseActivity replaceFragment ࣮૷ͷղઆ ڞ௨ͷ෦෼ @Override public void replaceFragment(BaseFragment fragment,

    @Nullable TransitionExtra extra) { if (extra != null) { Intent intent = PostArticleActivity.createIntent(this); Pair<View, String>[] sharedElements; if (!isEmpty(extra.getSharedElementPair())) { sharedElements = new Pair[extra.getSharedElementPair().size()]; for (int i = 0; i < extra.getSharedElementPair().size(); i++) { Pair<View, String> pair = extra.getSharedElementPair().get(i); if (pair.first != null && pair.second != null) { sharedElements[i] = pair; } } } else { sharedElements = new Pair[0]; } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { ActivityOptionsCompat options =
  36. 2018.2.8 BaseActivity replaceFragment ࣮૷ͷղઆ ڞ௨ͷ෦෼ new Pair[extra.getSharedElementPair().size()]; for (int i

    = 0; i < extra.getSharedElementPair().size(); i++) { Pair<View, String> pair = extra.getSharedElementPair().get(i); if (pair.first != null && pair.second != null) { sharedElements[i] = pair; } } } else { sharedElements = new Pair[0]; } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(this, sharedElements); ActivityCompat.startActivity(this, intent, options.toBundle()); } else { startActivity(intent); } } else { /*͔͜͜ΒFragmentͰ։͘৔߹ͷॲཧ*/ }
  37. 2018.2.8 PostArticleActivity TransitionΛҰ࣌ఀࢭ͢Δ ࣮૷ͷղઆ ڞ௨ͷ෦෼ @Override protected void onCreate(Bundle savedInstanceState)

    { // ৭ʑͳॳظԽͷॲཧΛ͢Δ // FragmentͷView͕ग़དྷ্͕Δ·ͰɺTransitionΛҰ࣌ఀࢭ͢Δ // ࠶։͸Fragmentଆ͔ΒݺΜͰ͋͛Δ supportPostponeEnterTransition(); }
  38. 2018.2.8 PostArticleActivity ҎԼͷTransitionSet͕ద༻͞Ε͍ͯΔ <transitionSet xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:duration="250" android:transitionOrdering="together"> <changeBounds android:interpolator="@anim/interpolator_transition"

    /> <changeTransform android:interpolator="@anim/interpolator_transition" /> <changeClipBounds android:interpolator="@anim/interpolator_transition" /> </transitionSet> ࣮૷ͷղઆ ڞ௨ͷ෦෼
  39. 2018.2.8 ࣮૷ͷղઆ Article

  40. 2018.2.8 Article Transition։࢝લ ࣮૷ͷղઆ Article • CardView • ImageView(Mark Zuckerberg)

    • ౤ߘऀΛදࣔ͢ΔϨΠΞ΢τ • Title • ͍͍Ͷ΍ίϝϯτϘλϯͷϨΠΞ΢τ
  41. 2018.2.8 Article Transition։࢝લ ࣮૷ͷղઆ Article • CardView • ImageView(Mark Zuckerberg)

    • ౤ߘऀΛදࣔ͢ΔϨΠΞ΢τ • Title • ͍͍Ͷ΍ίϝϯτϘλϯͷϨΠΞ΢τ
  42. 2018.2.8 Article Transition։࢝લ ࣮૷ͷղઆ Article • CardView • ImageView(Mark Zuckerberg)

    • ౤ߘऀΛදࣔ͢ΔϨΠΞ΢τ • Title • ͍͍Ͷ΍ίϝϯτϘλϯͷϨΠΞ΢τ
  43. 2018.2.8 Article Transition։࢝લ ࣮૷ͷղઆ Article • CardView • ImageView(Mark Zuckerberg)

    • ౤ߘऀΛදࣔ͢ΔϨΠΞ΢τ • Title • ͍͍Ͷ΍ίϝϯτϘλϯͷϨΠΞ΢τ
  44. 2018.2.8 Article Transition։࢝લ ࣮૷ͷղઆ Article • CardView • ImageView(Mark Zuckerberg)

    • ౤ߘऀΛදࣔ͢ΔϨΠΞ΢τ • Title • ͍͍Ͷ΍ίϝϯτϘλϯͷϨΠΞ΢τ
  45. 2018.2.8 Article Transition։࢝ޙং൫ ࣮૷ͷղઆ Article • CardView • ImageView(Mark Zuckerberg)

    • ౤ߘऀΛදࣔ͢ΔϨΠΞ΢τ • Title • ͍͍Ͷ΍ίϝϯτϘλϯͷϨΠΞ΢τ • CardViewͷSharedElementͱͯ͠ ഑ஔ͍ͯͨ͠ന͍͚ͩͷ FrameLayout
  46. 2018.2.8 Article Transition։࢝ޙऴ൫ ࣮૷ͷղઆ Article • CardView • ImageView(Mark Zuckerberg)

    • ౤ߘऀΛදࣔ͢ΔϨΠΞ΢τ • Title • ͍͍Ͷ΍ίϝϯτϘλϯͷϨΠΞ΢τ • CardViewͷSharedElementͱͯ͠ ഑ஔ͍ͯͨ͠ന͍͚ͩͷ FrameLayout
  47. 2018.2.8

  48. 2018.2.8 Article Shared Elements ࣮૷ͷղઆ Article 5JNFMJOF'SBNFOU 1PTU"SUJDMF'SBHNFOU 7JFX %FTDSJQUJPO

    7JFX %FTDSJQUJPO *NBHF7JFX Χʔυഎܠ *NBHF7JFX ΧόʔΠϝʔδ $BSE7JFX Χʔυ 'SBNF-BZPVU μϛʔͷഎܠ -JOFBS-BZPVU ౤ߘऀͷϨΠΞ΢τ -JOFBS-BZPVU ౤ߘऀͷϨΠΞ΢τ 5FYU7JFX λΠτϧ 5FYU7JFX λΠτϧ 5FYU7JFX ϝσΟΞ 5FYU7JFX ϝσΟΞ $POTUSBJOU-BZPVU ίϝϯτϘλϯͳͲ $POTUSBJOU-BZPVU ίϝϯτϘλϯͳͲ
  49. 2018.2.8 PostArticleFragment ϨΠΞ΢τߏ଄ <FrameLayout android:id="@+id/content_root"> ࣮૷ͷղઆ Article fragment_post_article.xml </FrameLayout> <android.support.constraint.ConstraintLayout

    android:id=“@+id/reaction"> <!--͍͍ͶͷϘλϯͱ͔ίϝϯτͷϘλϯͱ͔--> </android.support.constraint.ConstraintLayout>
  50. 2018.2.8 <FrameLayout android:id="@+id/content_root"> ࣮૷ͷղઆ Article <FrameLayout android:id="@+id/background_view" android:background="@drawable/background_post_article" /> </FrameLayout>

    <android.support.constraint.ConstraintLayout android:id=“@+id/reaction"> <!--͍͍ͶͷϘλϯͱ͔ίϝϯτͷϘλϯͱ͔--> </android.support.constraint.ConstraintLayout> PostArticleFragment ϨΠΞ΢τߏ଄ fragment_post_article.xml
  51. 2018.2.8 <FrameLayout android:id="@+id/content_root"> ࣮૷ͷղઆ Article <FrameLayout android:id="@+id/background_view" android:background="@drawable/background_post_article" /> <android.support.constraint.ConstraintLayout>

    <android.support.v4.widget.NestedScrollView android:id="@+id/parent_nested_scroll_view"> </android.support.v4.widget.NestedScrollView> </FrameLayout> <android.support.constraint.ConstraintLayout android:id=“@+id/reaction"> <!--͍͍ͶͷϘλϯͱ͔ίϝϯτͷϘλϯͱ͔--> </android.support.constraint.ConstraintLayout> PostArticleFragment ϨΠΞ΢τߏ଄ fragment_post_article.xml
  52. 2018.2.8 <FrameLayout android:id="@+id/content_root"> ࣮૷ͷղઆ Article <FrameLayout android:id="@+id/background_view" android:background="@drawable/background_post_article" /> <FrameLayout

    android:id="@+id/card"> <android.support.constraint.ConstraintLayout> <android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout> <android.support.v4.widget.NestedScrollView android:id="@+id/parent_nested_scroll_view"> </android.support.v4.widget.NestedScrollView> </FrameLayout> <android.support.constraint.ConstraintLayout android:id=“@+id/reaction"> <!--͍͍ͶͷϘλϯͱ͔ίϝϯτͷϘλϯͱ͔--> </android.support.constraint.ConstraintLayout> PostArticleFragment ϨΠΞ΢τߏ଄ fragment_post_article.xml
  53. 2018.2.8 <FrameLayout android:id="@+id/content_root"> ࣮૷ͷղઆ Article <FrameLayout android:id="@+id/background_view" android:background="@drawable/background_post_article" /> <FrameLayout

    android:id="@+id/card"> <android.support.constraint.ConstraintLayout> <android.support.v4.widget.NestedScrollView android:id="@+id/parent_nested_scroll_view"> <FrameLayout android:id="@+id/card"> <ImageView android:id="@+id/image_cover" /> <android.support.constraint.ConstraintLayout> <include android:id="@+id/layout_poster" layout="@layout/item_post_user" /> <TextView android:id="@+id/text_title" /> <TextView android:id="@+id/label_ad" /> <TextView android:id="@+id/text_source_media" /> <TextView android:id="@+id/text_published_at" /> </android.support.constraint.ConstraintLayout> </FrameLayout> PostArticleFragment ϨΠΞ΢τߏ଄ fragment_post_article.xml
  54. 2018.2.8 ࣮૷ͷղઆ Article layout="@layout/item_post_user" /> <TextView android:id="@+id/text_title" /> <TextView android:id="@+id/label_ad"

    /> <TextView android:id="@+id/text_source_media" /> <TextView android:id="@+id/text_published_at" /> </android.support.constraint.ConstraintLayout> </FrameLayout> <WebView android:id="@+id/web_view_short_article" /> <android.support.constraint.ConstraintLayout> </android.support.v4.widget.NestedScrollView> <android.support.constraint.ConstraintLayout android:id=“@+id/reaction"> <!--͍͍ͶͷϘλϯͱ͔ίϝϯτͷϘλϯͱ͔--> </android.support.constraint.ConstraintLayout> </FrameLayout> PostArticleFragment ϨΠΞ΢τߏ଄ fragment_post_article.xml
  55. 2018.2.8 @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup

    container, @Nullable Bundle savedInstanceState) { mBinding = FragmentPostArticleBinding.inflate(inflater, container, false); ViewCompat.setTransitionName(mBinding.imageCover, getString(R.string.transition_image_cover)); ViewCompat.setTransitionName(mBinding.backgroundView, getString(R.string.transition_background)); ViewCompat.setTransitionName(mBinding.layoutPoster.getRoot(), getString(R.string.transition_item_user)); ViewCompat.setTransitionName(mBinding.textTitle, getString(R.string.transition_text_title)); ViewCompat.setTransitionName(mBinding.textSourceMedia, getString(R.string.transition_item_source_media)); ViewCompat.setTransitionName(mBinding.reaction, getString(R.string.transition_item_reactions)); return mBinding.getRoot(); } ࣮૷ͷղઆ Article PostArticleFragment TransitionपΓͷίʔυ
  56. 2018.2.8 @Override public void onStart() { super.onStart(); mPostAccessor.getObservable() .compose(this.bindToLifecycle()) .subscribe(post

    -> { refreshPost(post, mState); getActivity().supportStartPostponedEnterTransition(); }, e -> recordError(null, this, e, null)); } ࣮૷ͷղઆ Article PostArticleFragment Ωϟογϡʹ͋Δهࣄͷσʔλ(post)Λऔಘ͠ɺ׬ྃޙTransitionΛ࠶։
  57. 2018.2.8 ϙΠϯτ • Transition։࢝લͷλΠϛϯάͰҰ࣌ఀࢭ͢Δ • Viewͷ४උ͕Ͱ͖ͨΒ࠶։ • Χʔυ͕expand͢ΔΑ͏ͳΞχϝʔγϣϯ ͸ͪΐͬͱͨ͠τϦοΫΛ࢖͍ͬͯΔ͚ͩɻ ೉͘͠͸ͳ͍

    ࣮૷ͷղઆ Article PostArticleFragment
  58. 2018.2.8 ࣮૷ͷղઆ Graphic contents

  59. 2018.2.8 Graphic contents Transition։࢝લ ࣮૷ͷղઆ Graphic contents • CardView •

    ImageView(Χʔυഎܠ) • ౤ߘऀΛදࣔ͢ΔϨΠΞ΢τ • Title
  60. 2018.2.8 Graphic contents ࣮૷ͷղઆ Graphic contents • CardView • ImageView(Χʔυഎܠ)

    • ౤ߘऀΛදࣔ͢ΔϨΠΞ΢τ • Title Transition։࢝લ
  61. 2018.2.8 Graphic contents ࣮૷ͷղઆ Graphic contents Transition։࢝લ • CardView •

    ImageView(Χʔυഎܠ) • ౤ߘऀΛදࣔ͢ΔϨΠΞ΢τ • Title
  62. 2018.2.8 Graphic contents ࣮૷ͷղઆ Graphic contents Transition։࢝લ • CardView •

    ImageView(Χʔυഎܠ) • ౤ߘऀΛදࣔ͢ΔϨΠΞ΢τ • Title
  63. 2018.2.8 Graphic contents Transition։࢝ޙং൫ • Χʔυશମ͕ը໘ΛຒΊΔ༻ʹ޿͕ͬͯ ͍͘ • ౤ߘऀ΍λΠτϧͳͲ΋ಉ͡Α͏ʹಈ͍ ͍ͯ͘

    ࣮૷ͷղઆ Graphic contents
  64. 2018.2.8 Graphic contents Transition։࢝ޙத൫ • എܠʹઃఆ͍ͯͨ͠ImageView͕ը໘ ͍ͬͺ͍ʹ޿͕Δ ࣮૷ͷղઆ Graphic contents

  65. 2018.2.8 Graphic contents Transition։࢝ޙऴ൫1/2 • ίϯςϯπͷϩʔυ͕ऴྃ͠ɺϔομʔ ෦෼͕ϑΣʔυΞ΢τ&্ʹফ͍͑ͯ͘ ࣮૷ͷղઆ Graphic contents

  66. 2018.2.8 Graphic contents Transition։࢝ޙऴ൫2/2 • ίϯςϯπͱഎܠը૾͕ΫϩεϑΣʔυ ͢ΔܗͰೖΕସΘΔ ࣮૷ͷղઆ Graphic contents

  67. 2018.2.8

  68. 2018.2.8 Graphic contents Shared Elements ࣮૷ͷղઆ 5JNFMJOF'SBNFOU (SBQIJD$POUFOUT'SBHNFOU 7JFX %FTDSJQUJPO

    7JFX %FTDSJQUJPO *NBHF7JFX Χʔυഎܠ *NBHF7JFX എܠը૾ -JOFBS-BZPVU ౤ߘऀͷϨΠΞ΢τ -JOFBS-BZPVU ౤ߘऀͷϨΠΞ΢τ 5FYU7JFX λΠτϧ 5FYU7JFX λΠτϧ 5FYU7JFX ϝσΟΞ 5FYU7JFX ϝσΟΞ Graphic contents
  69. 2018.2.8 GraphicContentsFragment ϨΠΞ΢τߏ଄ <android.support.constraint.ConstraintLayout android:id="@+id/content_root"> ࣮૷ͷղઆ fragment_graphic_contents.xml </android.support.constraint.ConstraintLayout> Graphic contents

  70. 2018.2.8 GraphicContentsFragment ϨΠΞ΢τߏ଄ <android.support.constraint.ConstraintLayout android:id="@+id/content_root"> ࣮૷ͷղઆ fragment_graphic_contents.xml </android.support.constraint.ConstraintLayout> Graphic contents

    <WebView android:id="@+id/web_view_graphic_content" /> <ImageView android:id="@+id/background_view" />
  71. 2018.2.8 GraphicContentsFragment ϨΠΞ΢τߏ଄ <android.support.constraint.ConstraintLayout android:id="@+id/content_root"> ࣮૷ͷղઆ fragment_graphic_contents.xml </android.support.constraint.ConstraintLayout> Graphic contents

    <WebView android:id="@+id/web_view_graphic_content" /> <ImageView android:id="@+id/background_view" />
  72. 2018.2.8 GraphicContentsFragment ϨΠΞ΢τߏ଄ <android.support.constraint.ConstraintLayout android:id="@+id/content_root"> ࣮૷ͷղઆ fragment_graphic_contents.xml </android.support.constraint.ConstraintLayout> Graphic contents

    <WebView android:id="@+id/web_view_graphic_content" /> <ImageView android:id="@+id/background_view" /> <android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout>
  73. 2018.2.8 GraphicContentsFragment ϨΠΞ΢τߏ଄ <android.support.constraint.ConstraintLayout android:id="@+id/content_root"> ࣮૷ͷղઆ fragment_graphic_contents.xml </android.support.constraint.ConstraintLayout> Graphic contents

    <WebView android:id="@+id/web_view_graphic_content" /> <ImageView android:id="@+id/background_view" /> <android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout> <FrameLayout android:id="@+id/header"> </FrameLayout>
  74. 2018.2.8 GraphicContentsFragment ϨΠΞ΢τߏ଄ <android.support.constraint.ConstraintLayout android:id="@+id/content_root"> ࣮૷ͷղઆ fragment_graphic_contents.xml Graphic contents <WebView

    android:id="@+id/web_view_graphic_content" /> <ImageView android:id="@+id/background_view" /> <android.support.constraint.ConstraintLayout> </android.support.constraint.ConstraintLayout> <FrameLayout android:id="@+id/header"> </FrameLayout> <android.support.constraint.ConstraintLayout> <include android:id="@+id/layout_poster" /> <TextView android:id="@+id/text_title" /> <TextView android:id="@+id/label_ad" /> <TextView android:id="@+id/text_source_media" /> <TextView android:id="@+id/text_published_at" /> </android.support.constraint.ConstraintLayout>
  75. 2018.2.8 GraphicContentsFragment TransitionपΓͷίʔυ1/2 ࣮૷ͷղઆ Graphic contents @Nullable @Override public View

    onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { mBinding = FragmentPostArticleSp1Rev2Binding.inflate(inflater, container, false); ViewCompat.setTransitionName(mBinding.backgroundView, getString(R.string.transition_background)); ViewCompat.setTransitionName(mBinding.textTitle, getString(R.string.transition_text_title)); ViewCompat.setTransitionName(mBinding.layoutPoster.getRoot(), getString(R.string.transition_item_user)); ViewCompat.setTransitionName(mBinding.textSourceMedia, getString(R.string.transition_item_source_media)); return mBinding.getRoot(); }
  76. 2018.2.8 GraphicContentsFragment TransitionपΓͷίʔυ2/2 ࣮૷ͷղઆ Graphic contents @Override public void onPageFinished(WebView

    view, String url) { super.onPageFinished(view, url); TransitionSet transitionSet = new TransitionSet().setDuration(400).setStartDelay(200); Fade fadeTransition = new Fade(); Transition slideUpTransition = new Slide(Gravity.TOP) .setStartDelay(100) .excludeTarget(R.id.background_view, true); transitionSet.addTransition(fadeTransition); transitionSet.addTransition(slideUpTransition); transitionSet.setInterpolator(AnimationUtils.loadInterpolator( getContext(), R.anim.accelerate_quad)); TransitionManager.beginDelayedTransition(((ViewGroup) getView()), transitionSet); mBinding.card.setVisibility(View.INVISIBLE); mBinding.backgroundView.setVisibility(View.INVISIBLE); view.setVisibility(View.VISIBLE); }
  77. 2018.2.8 @Override public void onStart() { super.onStart(); mPostAccessor.getObservable() .compose(this.bindToLifecycle()) .subscribe(post

    -> { refreshPost(post, mState); getActivity().supportStartPostponedEnterTransition(); }, e -> recordError(null, this, e, null)); } ࣮૷ͷղઆ GraphicContentsFragment Ωϟογϡʹ͋Δهࣄͷσʔλ(post)Λऔಘ͠ɺ׬ྃޙTransitionΛ࠶։ Graphic contents
  78. 2018.2.8 ϙΠϯτ • Transition։࢝લͷλΠϛϯάͰҰ࣌ఀࢭ͢Δ • Viewͷ४උ͕Ͱ͖ͨΒ࠶։ • ࣮ࡍʹେ͖͘ಈ͍͍ͯΔͷ͸ImageView͚ͩ • ࡉ͔͘ಈ͍͍ͯΔΞΠςϜୡ͸

    TransitionFrameworkͷ͓͔͛ • ΞχϝʔγϣϯͷAPI͸৭ʑ͋ΔͷͰɺཁॴཁ ॴͰ૊Έ߹Θͯ͠࢖͍ͬͯ͘ ࣮૷ͷղઆ GraphicContentsFragment Graphic contents
  79. 2018.2.8 Ξχϝʔγϣϯ࣮૷ͷצॴ ·ͣ͸ਅͬ޲͔Βߟ͑ͣʹ΍Ζ͏

  80. 2018.2.8 ࡶʹ࡞Δ Ξχϝʔγϣϯ࣮૷ͷצॴ ·ͣ͸ਅͬ޲͔Βߟ͑ͣʹ΍Ζ͏

  81. 2018.2.8 ὃ͢Α͏ʹߟ͑Δ Ξχϝʔγϣϯ࣮૷ͷצॴ ·ͣ͸ਅͬ޲͔Βߟ͑ͣʹ΍Ζ͏

  82. 2018.2.8 ਅࣅΛ͢Δ Ξχϝʔγϣϯ࣮૷ͷצॴ ·ͣ͸ਅͬ޲͔Βߟ͑ͣʹ΍Ζ͏

  83. 2018.2.8 ఘΊͳ͍ Ξχϝʔγϣϯ࣮૷ͷצॴ ·ͣ͸ਅͬ޲͔Βߟ͑ͣʹ΍Ζ͏

  84. 2018.2.8 ΞχϝʔγϣϯͷDebug

  85. 2018.2.8 • AnimatorεέʔϧΛ5xʙ10xʹ͢Δ • ϨΠΞ΢τͷڥքઢΛදࣔ͢Δ • γϣʔτΧοτͱͯ͠௨஌ͷॴʹஔ͍ͱ͘ ͱྑ͍͔΋ ΞχϝʔγϣϯͷDebug ։ൃऀΦϓγϣϯ

  86. 2018.2.8 • android:animateLayoutChanges=“true" ͕ViewGroupʹઃఆ͞Ε͍ͯΔ͔΋ʁ • ࣗ෼Ͱద༻ͨ͠ΞχϝʔγϣϯͱίϯϑϦ ΫτΛى͍ͯ͜͠ΔՄೳੑ͕͋Δ • clipChildren/clipToPaddingͷࢦఆΛ͍ͬ͡ ͯΈΔ

    • େ͖͘࿮Λ௒͑ͯΞχϝʔγϣϯ͢Δ࣌͸ ্هͷࢦఆ͕ฉ͍ͯ͘Δɻfalseʹ͢Δ͜ͱ ͰViewGroupͷ࿮Λඈͼग़ͯ͠ಈ͘Α͏ ʹͰ͖Δ͔΋͠Εͳ͍ ΞχϝʔγϣϯͷDebug มͳಈ͖Λ͍ͯͨ͠Β1/2 ҎԼͷ߲໨ΛٙͬͯΈͯ΋͍͍͔΋
  87. 2018.2.8 • Ұ୴ϨΠΞ΢τϑΝΠϧΛ࡞Γ௚ͯ͠ΈΔ • ແཧͷ͋ΔϨΠΞ΢τϑΝΠϧʹͳ͍ͬͯ Δ͔΋͠Εͳ͍ • ֊૚͕ਂ͍ͱ΍΍͘͜͠ͳΔɻͳΔ΂͘ ConstrainLayoutͳͲΛ࢖ͬͯ֊૚Λઙ͘ ͢Δ͜ͱ͕ग़དྷͳ͍͔ߟ͑Δ

    • Ұͭͷख๏͚ͩͰΰϦԡ͠͠Α͏ͱ͍ͯ͠ͳ ͍͔ʁ • ଞʹָͳํ๏͕ͳ͍͔ݕূ͢Δɻ·ͨɺࣅ ͨΑ͏ͳΞϓϦ͕ͳ͍͔୳ͯ͠ΈΔ ΞχϝʔγϣϯͷDebug มͳಈ͖Λ͍ͯͨ͠Β2/2 ҎԼͷ߲໨ΛٙͬͯΈͯ΋͍͍͔΋
  88. 2018.2.8 • Shared Element Transition͸αϯϓϧίʔυ ࣗମ͸؆୯ͳ΋ͷ͕ଟ͍͚Ͳɺ࣮ࡍʹ૊Έࠐ ΉͱͳΔͱɺϨΠΞ΢τϑΝΠϧͷ࡞Γํ౳ ޻෉͕ඞཁʹͳΔ • Shared

    Element Transition͸Ұ࣌ఀࢭ/࠶։ ͕ίϯτϩʔϧͰ͖Δ • ͜·ͬͨΒɺҰ୴Ϧηοτͯ͠ߟ͑Δɻ·ͨɺ ࣅͯΔΞϓϦΛ୳ͯ͠Α͘؍࡯͢Δ ·ͱΊ ·ͱΊ
  89. 2018.2.8 Thanks!