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

実例で理解する Material Design Animation

Ryo Sakaguchi
February 08, 2018

実例で理解する Material Design Animation

DroidKaigi 2018 2/8 Room2

Ryo Sakaguchi

February 08, 2018
Tweet

More Decks by Ryo Sakaguchi

Other Decks in Programming

Transcript

  1. 2018.2.8 Ryo Sakaguchi @wakwak3125 • Wantedly, Inc • Android application

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

    developer • Wantedly People • Music, Guitar, UI/UX About me
  3. 2018.2.8 Article ࿩୊ͷهࣄΛදࣔ͢Δը໘ • ഑৴͞ΕΔ࿩୊Λදࣔ͢Δը໘ • Ϣʔβʔʹରͯ͠஫໨ͯ͠΄͍͠ʮը૾ʯ Λ࣠ʹΞχϝʔγϣϯ͢Δɻ • RecyclerViewʹΧʔυܕͷΞΠςϜΛฒ

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

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

    Timelineͷഎܠશମʹϒϥʔ͕͔͔ͬ ͨ΋ͷ͕هࣄͷग़ݱͱڞʹΫϩεϑΣʔ υ͢Δ • ࠓճϝΠϯͰ࿩Λ͢Δͭ΋Γͷɺ SharedElementTransitionͱ͸ҧ͏͚ ͲɺҰԠ঺հ ʮ࿩୊ʯػೳͷΞχϝʔγϣϯ঺հ Timeline
  6. 2018.2.8 ͔͍͍͔ͬ͜Βʁ ͚ͩ͡Όͳ͍Ͱ͢ • ΞχϝʔγϣϯʹΑͬͯɺϢʔβʔʹ ஫໨ͯ͠΄͍͠΋ͷΛΞϐʔϧͰ͖Δ • ࢖͍ͬͯͯɺಥવίϯςϯπ͕ೖΕସ Θͬͨ෩ʹײͯ͡͠·͏Ϣʔβʔ΋ډ Δ͸ͣɻ

    • ΍Βͳ͍ΑΓ͸΍ͬͨ΄͏͕ઈରྑ͍ • ΍Γ͗͢͸ྑ͘ͳ͍ɻ͚Ͳɺ·ͣ ͸࡞͔ͬͯΒ࡟͍ͬͯ͘ͷ͕େࣄ • ΋ͪΖΜ͔͍͍ͬͬͯ͜΋ͷ͋Δʂ ΞχϝʔγϣϯͬͯͳΜͰඞཁͳͷʁ
  7. 2018.2.8 ࣮૷ͷղઆ • Shared Element Transitionͷجຊͷ ͓͞Β͍ • ֤ػೳ(Article/Graphic contents)

    ʹґଘ͠ͳ͍෦෼ͷڞ௨࣮૷ͷ࿩ • ֤ػೳຖʹߦ͍ͬͯΔಛผͳ෦෼ͷ࿩ • Article • Graphic content
  8. 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*/
  9. 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); }
  10. 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"); } }
  11. 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
  12. 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 ); } }
  13. 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Λ༩͍͑ͯ͘
  14. 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);
  15. 2018.2.8 BaseFragment replaceFragment ࣮૷ͷղઆ ڞ௨ͷ෦෼ public void replaceFragment(@NonNull BaseFragment fragment,

    @Nullable TransitionExtra extra) { // BaseActivity͕listenerΛ࣮૷͍ͯ͠ΔͷͦͪΒʹϦϨʔ͢Δ getListener().replaceFragment(fragment, extra); }
  16. 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 =
  17. 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Ͱ։͘৔߹ͷॲཧ*/ }
  18. 2018.2.8 PostArticleActivity TransitionΛҰ࣌ఀࢭ͢Δ ࣮૷ͷղઆ ڞ௨ͷ෦෼ @Override protected void onCreate(Bundle savedInstanceState)

    { // ৭ʑͳॳظԽͷॲཧΛ͢Δ // FragmentͷView͕ग़དྷ্͕Δ·ͰɺTransitionΛҰ࣌ఀࢭ͢Δ // ࠶։͸Fragmentଆ͔ΒݺΜͰ͋͛Δ supportPostponeEnterTransition(); }
  19. 2018.2.8 Article Transition։࢝લ ࣮૷ͷղઆ Article • CardView • ImageView(Mark Zuckerberg)

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

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

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

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

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

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

    • ౤ߘऀΛදࣔ͢ΔϨΠΞ΢τ • Title • ͍͍Ͷ΍ίϝϯτϘλϯͷϨΠΞ΢τ • CardViewͷSharedElementͱͯ͠ ഑ஔ͍ͯͨ͠ന͍͚ͩͷ FrameLayout
  26. 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 ίϝϯτϘλϯͳͲ
  27. 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
  28. 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
  29. 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
  30. 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
  31. 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
  32. 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पΓͷίʔυ
  33. 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Λ࠶։
  34. 2018.2.8 Graphic contents Transition։࢝લ ࣮૷ͷղઆ Graphic contents • CardView •

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

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

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

    ImageView(Χʔυഎܠ) • ౤ߘऀΛදࣔ͢ΔϨΠΞ΢τ • Title
  38. 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
  39. 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>
  40. 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>
  41. 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>
  42. 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(); }
  43. 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); }
  44. 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
  45. 2018.2.8 ϙΠϯτ • Transition։࢝લͷλΠϛϯάͰҰ࣌ఀࢭ͢Δ • Viewͷ४උ͕Ͱ͖ͨΒ࠶։ • ࣮ࡍʹେ͖͘ಈ͍͍ͯΔͷ͸ImageView͚ͩ • ࡉ͔͘ಈ͍͍ͯΔΞΠςϜୡ͸

    TransitionFrameworkͷ͓͔͛ • ΞχϝʔγϣϯͷAPI͸৭ʑ͋ΔͷͰɺཁॴཁ ॴͰ૊Έ߹Θͯ͠࢖͍ͬͯ͘ ࣮૷ͷղઆ GraphicContentsFragment Graphic contents
  46. 2018.2.8 • android:animateLayoutChanges=“true" ͕ViewGroupʹઃఆ͞Ε͍ͯΔ͔΋ʁ • ࣗ෼Ͱద༻ͨ͠ΞχϝʔγϣϯͱίϯϑϦ ΫτΛى͍ͯ͜͠ΔՄೳੑ͕͋Δ • clipChildren/clipToPaddingͷࢦఆΛ͍ͬ͡ ͯΈΔ

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

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

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