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

実例で理解する Material Design Animation

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Ryo Sakaguchi Ryo Sakaguchi
February 08, 2018

実例で理解する Material Design Animation

DroidKaigi 2018 2/8 Room2

Avatar for Ryo Sakaguchi

Ryo Sakaguchi

February 08, 2018

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