$30 off During Our Annual Pro Sale. View Details »
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
View Animation
Search
satsukies
October 02, 2017
Programming
1
850
View Animation
View Animation in Android
satsukies
October 02, 2017
Tweet
Share
More Decks by satsukies
See All by satsukies
5分で作るモックサーバー
satsukies
0
1.3k
Android スキルセットをフル活用して始めるスマートテレビアプリ開発
satsukies
1
960
Android TVに関するアップデート / What's new on Android TV
satsukies
0
220
Kotlin Nativeでクロスプラットフォーム開発 / Cross-platform development with Kotlin Native
satsukies
1
950
Navigation Component
satsukies
5
4.1k
「OK google, プロジェクトのbuildして」
satsukies
2
1.6k
いまさら始めるInstant App
satsukies
1
430
Other Decks in Programming
See All in Programming
手が足りない!兼業データエンジニアに必要だったアーキテクチャと立ち回り
zinkosuke
0
780
生成AIを利用するだけでなく、投資できる組織へ
pospome
2
370
AtCoder Conference 2025「LLM時代のAHC」
imjk
2
540
LLMで複雑な検索条件アセットから脱却する!! 生成的検索インタフェースの設計論
po3rin
4
870
マスタデータ問題、マイクロサービスでどう解くか
kts
0
110
大規模Cloud Native環境におけるFalcoの運用
owlinux1000
0
160
tparseでgo testの出力を見やすくする
utgwkk
2
260
著者と進める!『AIと個人開発したくなったらまずCursorで要件定義だ!』
yasunacoffee
0
150
UIデザインに役立つ 2025年の最新CSS / The Latest CSS for UI Design 2025
clockmaker
18
7.6k
実は歴史的なアップデートだと思う AWS Interconnect - multicloud
maroon1st
0
230
TUIライブラリつくってみた / i-just-make-TUI-library
kazto
1
400
TestingOsaka6_Ozono
o3
0
170
Featured
See All Featured
Balancing Empowerment & Direction
lara
5
810
We Have a Design System, Now What?
morganepeng
54
7.9k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
160
Thoughts on Productivity
jonyablonski
73
5k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
1.9k
My Coaching Mixtape
mlcsv
0
7
The Illustrated Children's Guide to Kubernetes
chrisshort
51
51k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
132
19k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
320
Digital Ethics as a Driver of Design Innovation
axbom
PRO
0
130
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
0
2.2k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
0
110
Transcript
7JFX"OJNBUJPO 4BUPTIJ5BLFEB "CFNB57*OD
8IPJT
8IPJT ాɹஐ 5BLFEBɹ4BUPTIJ ˡTBUTVLJFT ɹɹ$ZCFS"HFOUʹ৽ଔೖࣾ ʙɹ"CFNB57ʹ"OESPJEΤϯδχΞͰଐ
"OJNBUJPO
"OJNBUJPO 7JFX"OJNBUJPO 1SPQFSUZ"OJNBUJPO %SBXBCMF"OJNBUJPO
"OJNBUJPO 7JFX"OJNBUJPO 1SPQFSUZ"OJNBUJPO %SBXBCMF"OJNBUJPO BMQIB SPUBUF TDBMF USBOTMBUF ͍͍͢ɾ؆୯ ݟ͚͕ͨͩมԽ͢ΔΞχϝʔγϣϯ
// viewͷalpha͕0͔Β13ඵ͔͚ͯมԽ͢ΔΞχϝʔγϣϯ (findViewById(R.id.image_view) as? ImageView)?.apply { startAnimation(AlphaAnimation(0f, 1f).apply { duration = 3000 }) }
"OJNBUJPO 7JFX"OJNBUJPO 1SPQFSUZ"OJNBUJPO "1*͔Β࣮͞Εͨ৽͍͠BOJNBUPS ෳࡶͳΞχϝʔγϣϯΛදݱՄೳ ݟ͚ͨͩͰͳ࣮͘ࡍͷҐஔมԽ <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering=“together"> <objectAnimator
android:duration="3000" android:propertyName=“alpha" android:valueFrom="0f" android:valueTo="1f"/> <objectAnimator android:duration="3000" android:propertyName="translationY" android:valueFrom="0dp" android:valueTo="100dp"/> </set> %SBXBCMF"OJNBUJPO
"OJNBUJPO 1SPQFSUZ"OJNBUJPO %SBXBCMF"OJNBUJPO ը૾ϦιʔεΛෳຕར༻ͯ͠ ύϥύϥອըͷΑ͏ʹ࠶ੜͤ͞Δ 7JFX"OJNBUJPO <?xml version="1.0" encoding="utf-8"?> <animation-list
xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false" android:visible="true" > <item android:drawable=“@drawable/pict0" android:duration="300" /> <item android:drawable="@drawable/pict1" android:duration="300" /> <item android:drawable="@drawable/pict2" android:duration="300" /> <item android:drawable="@drawable/pict3" android:duration="300" /> <item android:drawable="@drawable/pict4" android:duration="300" /> </animation-list>
.BUFSJBM%FTJHO
.BUFSJBM%FTJHO w .BUFSJBMJTUIFNFUBQIPS w #PME HSBQIJD JOUFOUJPOBM w .PUJPOQSPWJEFTNFBOJOH ҙຯͷ͋Δಈ͖ΛϢʔβʹࣔ͢͜ͱͰ
ɾࢹ֮తʹҙΛҾ͖͚ͭΔ ɾཁૉͷग़ݱมܗɺҠಈΛ௨ͯ͡࿈ଓੑΛ͑Δ ը໘ભҠ͕࣌࠷࿈ଓੑ͕ࣦΘΕͦ͢͏
ը໘ભҠͷΧελϚΠζ
ը໘ભҠͷΧελϚΠζ https://developer.android.com/training/material/animations.html#Transitions (PPHMF%FWFMPQFSTͷ ʮΞΫςΟϏςΟભҠΛΧελϚΠζ͢ΔʯʹΑΕ ȜȄȨǠȩȅǴǢȱǠȕȨƵ!CTIVITYTRANSITIONS ᮊǠǭȄǡȑȄǡჟᮋƮƶųΒឬƠǒᖽᇽƵᣨƮƵ Ы˗NjدъǙឬƟƭųओƵϜǑଖƏƲᗆᗉƱ ƫƱƓǑǙেƦƢDžƠŴ લޙͷΞΫςΟϏςΟͰڞ௨ͷΞΠίϯը૾ݟग़͠ςΩετͳͲ͕ଘࡏ͢Δ߹ʹ ڞ௨͢Δཁૉͷද͕ࣔҾ͖ܧ͕Ε͍ͯΔΑ͏ʹݟͤΔ͜ͱͰ࿈ଓੑΛදݱ͢Δ
"DUJWJUZ5SBOTJUJPOTͷछྨ
"DUJWJUZ5SBOTJUJPOTͷछྨ &OUFS &YJU 4IBSFE&MFNFOUT
"DUJWJUZ5SBOTJUJPOTͷछྨ &OUFS &YJU 4IBSFE&MFNFOUT "DUJWJUZͷWJFX͕ͲͷΑ͏ʹը໘ೖͬͯ͘Δ͔Λܾఆ
"DUJWJUZ5SBOTJUJPOTͷछྨ &OUFS &YJU 4IBSFE&MFNFOUT "DUJWJUZͷWJFX͕ͲͷΑ͏ʹը໘͔Βग़ͯߦ͔͘Λܾఆ
"DUJWJUZ5SBOTJUJPOTͷछྨ &OUFS &YJU 4IBSFE&MFNFOUT ը໘্ʹ͋Δڞ௨ͷཁૉʢྫ͑*NBHF7JFXͱ͔ʣΛ ͲͷΑ͏ʹΞχϝʔγϣϯͤ͞Δ͔ɻ "1*͔Β࣮͞Εར༻Մೳʂ αϙʔτϥΠϒϥϦʹೖ͍ͬͯͳ͍ͷ͕ͪΐͬͱ೦
(PPHMF1MBZ4UPSF
None
Ґͩͱಈ͖͕গͳͯ͘ Α͔͘Βͳ͍ʁ!
Ξχϝʔγϣϯ εέʔϧY
"CFNB57ʹ
None
ͳΒ͜͜ʹ ΞχϝʔγϣϯΛʂ
7JFX"OJNBUJPO 4BUPTIJ5BLFEB "CFNB57*OD
7JFX"OJNBUJPO 4BUPTIJ5BLFEB "CFNB57*OD 5SBOTJUJPO
#BTJDJNQMFNFOU
#BTJDJNQMFNFOU /PSNBM.BTUFS"DUJWJUZLU val intent = Intent(context, SharedMasterActivity::class.java) val optionsCompat =
ActivityOptionsCompat.makeSceneTransitionAnimation( this, targetView, targetView.transitionName) startActivity(intent, optionsCompat.toBundle()) ΞχϝʔγϣϯରͷWJFX //viewͷΠϯελϯεϝιου targetView.setTransitionName("hogehoge") //ViewCompatΫϥεͷΫϥεϝιου ViewCompat.setTransitionName(targetView, "hogehoge") android:transitionName="hogehoge"
#BTJDJNQMFNFOU XJUIඇಉظ௨৴ ભҠઌͱભҠݩͰผʑͷը૾Λ͍ͬͯΔ߹ʜ ը૾ͷऔಘ͕Ξχϝʔγϣϯ։࢝ʹؒʹ߹Θͳ͍ʂ
"EWBODFEJNQMFNFOU
"EWBODFEJNQMFNFOU ݺͼग़ͨ͠λΠϛϯάͰ5SBOTJUJPO"OJNBUJPOΛ։࢝ͤ͞Δ QPTUQPOF&OUFS5SBOTJUJPO TUBSU1PTUQPOFE&OUFS5SBOTJUJPO 5SBOTJUJPO"OJNBUJPOͷ։࢝Λࢭ͢Δ Ξχϝʔγϣϯͷ։࢝λΠϛϯάΛ ίʔυଆͰίϯτϩʔϧՄೳ
"EWBODFEJNQMFNFOU override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) supportPostponeEnterTransition() // Ξχϝʔγϣϯࢭ
~~~~~~~~~~~~~~~ fun startEnterTransition() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return supportStartPostponedEnterTransition(); // Ξχϝʔγϣϯ࠶։ }
"EWBODFEJNQMFNFOU (MJEF1JDBTTPͷ$BMMCBDLʹࠐΜͰΈΔ ImageView targetImageView = (ImageView)findViewById(R.id.image_header); //Glideͷ߹(4.0-RC0) Glide.with(this) .load("http://hogehoge.com/fugafuga") .listener(new
RequestListener() { @Override public boolean onResourceReady(Object resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { startPostponedEnterTransition() return false; } }) .into(targetImageView); //Picassoͷ߹ Picasso.with(this) .load("http://hogehoge.com/fugafuga").into(targetImageView, new Callback(){ @Override public void onSuccess() { startPostponedEnterTransition() } });
ΫϦοΫ͔ͯ͠ΒΞχϝʔγϣϯ·Ͱͷػ͕࣌ؒࢥͬͨҎ্ʹ͍"
ϢʔβମݧΛҡ͍࣋ͨ͠
ϢʔβମݧΛҡ͍࣋ͨ͠ ಛʹߟ͑ͣγϯϓϧʹΞχϝʔγϣϯͤ͞Δͱ ɾΞϓϦ͕ϑϦʔζ͍ͯ͠ΔΑ͏ʹݟ͑ͯ͠·͏ ɾը૾͕ϩʔυ͞ΕΔ·ͰCBDLHSPVOE͕ݟ͑ݟ͑ ը૾ͷಡΈࠐΈΛͬͯΞχϝʔγϣϯ͢Δͱ ɾ్தͰը૾͕ϩʔυ͞Εͯද͕ࣔมʹͳΔ͜ͱ Ͳ͏ʹ͔ͯ͠ը૾Λૉૣ͘ϩʔυ͍ͨ͠ʜ"
None
ϢʔβମݧΛҡ͍࣋ͨ͠ (MJEFͷαϜωΠϧදࣔػೳΛ׆༻ ɾಉ͡WJFXͰෳͷը૾Λಉ࣌ʹಡΈࠐΊΔ ɾαϜωΠϧը૾ͷMPBEʹରͯ͠DBMMCBDL͕͚ͭΒΕΔ αϜωΠϧදࣔ Ξχϝʔγϣϯ։࢝ ݩը૾දࣔ
5SBOTJUJPOXJUIUIVNC
5SBOTJUJPOXJUIUIVNC ᶃ*OUFOUʹΩϟογϡࡁΈը૾ͷ63-ΛͤΔ ᶄαϜωΠϧಡΈࠐΈʹ*OUFOUͷ63-Λ͏
5SBOTJUJPOXJUIUIVNC ᶃ*OUFOUʹΩϟογϡࡁΈը૾ͷ63-ΛͤΔ ᶄαϜωΠϧಡΈࠐΈʹ*OUFOUͷ63-Λ͏ binding.getRoot().setOnClickListener(v -> episodeSelectListener.action( ep, ep.getEpisodeListThumbnail().with(options).url(), // ΩϟογϡࡁΈͷը૾URL
binding.episodeThumbnail, binding.vdSeriesThumbnailFreeMark, binding.episodePlayMark)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Intent intent = new Intent(this, DstActivity.class); intent.putExtra(“extra_url”, thumbnailUrlString);
5SBOTJUJPOXJUIUIVNC ᶃ*OUFOUʹΩϟογϡࡁΈը૾ͷ63-ΛͤΔ ᶄαϜωΠϧಡΈࠐΈʹ*OUFOUͷ63-Λ͏ //͢ͰʹMasterActivityͰऔಘࡁΈͰ͋Ζ͏ը૾ΛαϜωΠϧͱͯ͠ར༻͢Δ .thumbnail( Glide.with(imageView.getContext()) .load(imageThumbURL) .listener(new RequestListener<Drawable>() {
@Override public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) return false; } @Override public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) { supportStartPostponedEnterTransition(); // ಡΈࠐΈྃͰΞχϝʔγϣϯ࣮ߦ return false; }}) .apply(new RequestOptions().skipMemoryCache(true) .diskCacheStrategy(DiskCacheStrategy.AUTOMATIC))) .into(imageView);
ରࡦલ ରࡦޙ
"CFNB57BQQʜ
ͦͷଞ5JQT
ͦͷଞ5JQT TUBUVTOBWJHBUJPOCBSʹඃͤͳ͍ WJFX͕ݟΕͯͨΒΞχϝʔγϣϯ͠ͳ͍
ͦͷଞ5JQT TUBUVTOBWJHBUJPOCBSʹඃͤͳ͍ εςʔλεόʔφϏήʔγϣϯόʔ 4IBSFE&MFNFOU5SBOTJUJPOʹؚΊΔ // navigation bar View nav =
findViewById(android.R.id.navigationBarBackground); // status bar View stat = findViewById(android.R.id.statusBarBackground); Pair<View, String> navPair = new Pair<>(nav, "nav"); Pair<View, String> statPair = new Pair<>(stat, "stat"); ActivityOptionsCompat.makeSceneTransitionAnimation(this, navPair, statPair); WJFX͕ݟΕͯͨΒΞχϝʔγϣϯ͠ͳ͍
ͦͷଞ5JQT TUBUVTOBWJHBUJPOCBSʹඃͤͳ͍ WJFX͕ݟΕͯͨΒΞχϝʔγϣϯ͠ͳ͍
ͦͷଞ5JQT TUBUVTOBWJHBUJPOCBSʹඃͤͳ͍ ಈతͳΞχϝʔγϣϯ࣮ߦՄ൱ͷ੍ޚ ɾը໘ճస͕ൃੜͨ͠ΒΞχϝʔγϣϯΛ͠ͳ͍ ɾαϜωΠϧ͕ݟΕ͍ͯΔͱ͖Ξχϝʔγϣϯ͠ͳ͍ 4IBSFE&MFNFOU$BMMCBDLͰ ΞχϝʔγϣϯͷΩϟϯηϧॲཧΛ࣮
ͦͷଞ5JQT TUBUVTOBWJHBUJPOCBSʹඃͤͳ͍ ಈతͳΞχϝʔγϣϯ࣮ߦՄ൱ͷ੍ޚ 4IBSFE&MFNFOU$BMMCBDLͰ ΞχϝʔγϣϯͷΩϟϯηϧॲཧΛ࣮ setEnterSharedElementCallback(new SharedElementCallback() { @Override public
void onMapSharedElements(List<String> names, Map<String, View> sharedElements) { // Ξχϝʔγϣϯରview͕ݟΕ͍ͯΔ߹ΞχϝʔγϣϯΛ࣮ߦ͠ͳ͍ shouldClearSharedElements |= !Stream.of(sharedElements) .filter(item -> item.getValue() != null) .allMatch(item -> viewBehavior.checkViewContains(item.getValue())); if (shouldClearSharedElements) { names.clear(); sharedElements.clear(); } } });
ͦͷଞ5JQT TUBUVTOBWJHBUJPOCBSʹඃͤͳ͍ ಈతͳΞχϝʔγϣϯ࣮ߦՄ൱ͷ੍ޚ શදࣔ ݟΕ
4VNNBSZ
4VNNBSZ "OJNBUJPOʹछྨ͕͍Ζ͍Ζ "DUJWJUZ5SBOTJUJPO࿈ଓੑΛ͑ΔͷʹޮՌత গ͠ͷίʔυमਖ਼Ͱ"OJNBUJPOͷద༻͕Մೳ ඇಉظॲཧͱซ༻͢Δ࣌ҙΛ͏ඞཁ͋Γ
4VNNBSZ "OJNBUJPOʹछྨ͕͍Ζ͍Ζ "DUJWJUZ5SBOTJUJPO࿈ଓੑΛ͑ΔͷʹޮՌత গ͠ͷίʔυमਖ਼Ͱ"OJNBUJPOͷద༻͕Մೳ ඇಉظॲཧͱซ༻͢Δ࣌ҙΛ͏ඞཁ͋Γ 7JFX"OJNBUJPO 1SPQFSUZ"OJNBUJPO %SBXBCMF"OJNBUJPO "DUJWJUZ5SBOTJUJPOT
4VNNBSZ "OJNBUJPOʹछྨ͕͍Ζ͍Ζ "DUJWJUZ5SBOTJUJPO࿈ଓੑΛ͑ΔͷʹޮՌత લޙͷΞΫςΟϏςΟͰҎԼͷΑ͏ͳڞ௨ཁૉ͕ଘࡏ͢Δ߹ ɾΞΠίϯը૾ ɾݟग़͠ςΩετ ͜ΕΒͷද͕ࣔҾ͖ܧ͕Ε͍ͯΔΑ͏ʹݟͤΔ͜ͱͰ࿈ଓੑΛදݱ͢Δ গ͠ͷίʔυमਖ਼Ͱ"OJNBUJPOͷద༻͕Մೳ ඇಉظॲཧͱซ༻͢Δ࣌ҙΛ͏ඞཁ͋Γ
4VNNBSZ "OJNBUJPOʹछྨ͕͍Ζ͍Ζ গ͠ͷίʔυमਖ਼Ͱ"OJNBUJPOͷద༻͕Մೳ ඇಉظॲཧͱซ༻͢Δ࣌ҙΛ͏ඞཁ͋Γ "DUJWJUZ5SBOTJUJPO࿈ଓੑΛ͑ΔͷʹޮՌత USBOTJUJPO/BNFͷ ༩ 4IBSFE&MFNFOU 5SBOTJUJPOͷ࣮ߦڐՄ "DUJWJUZ0QUJPOT͖Ͱ
"DUJWJUZ࣮ߦ
4VNNBSZ "OJNBUJPOʹछྨ͕͍Ζ͍Ζ "DUJWJUZ5SBOTJUJPO࿈ଓੑΛ͑ΔͷʹޮՌత গ͠ͷίʔυमਖ਼Ͱ"OJNBUJPOͷద༻͕Մೳ ඇಉظॲཧͱซ༻͢Δ࣌ҙΛ͏ඞཁ͋Γ ඞཁʹԠͯ͡Ξχϝʔγϣϯͷ࣮ߦλΠϛϯάΛ੍ޚ QPTUQPOF&OUFS5SBOTJUJPO TUBSU1PTUQPOFE&OUFS5SBOTJUJPO Ξχϝʔγϣϯͷ ࠶։
Ξχϝʔγϣϯͷ ։࢝ࢭ αϜωΠϧಡΈࠐΈ
5IBOLZPV !TBUTVLJFT