RecyclerViewの中の要素をshared elementsにしてアニメーションする
今作っているツイッタークライアントは、タイムラインのユーザアイコンがタップされたらユーザ情報Activityに遷移するのだが、そのときにタップされたユーザアイコンが移動してユーザ情報Activityのユーザアイコンに重なるアニメーションを実装した。現時点ではAndroid 5.0 (API level 21)以上で有効。
まずは遷移元(タイムライン)と先(ユーザ情報)のActivityにWindow.requestFeature()
する。
// setContentView()の前に行う if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); }
遷移元と先のビューにユニークなtransitionName
をつける。RecyclerView
の中の要素にtransitionName
をつけるときはアニメーションさせようとする直前にセットしておかないとユニークにならないようで、カスタムビューの中でinflateした後にセットするとうまくいかなかった(タイムライン→ユーザ情報はうまくいくが、そこからbackボタンで戻るときにアニメーションの起点が右下とか左下になったりした)。クリックされたビューがアニメーションするので、クリックリスナの中でやってしまっている。
userIcon.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { ViewCompat.setTransitionName(view, "user_icon"); } });
ActivityOption
を渡してstartActivity()
する。同様に上のコードのクリックリスナの中でやっている。
Intent intent = new Intent(context, UserInfoActivity.class); ActivityCompat.startActivity(this, intent, ActivityOptionsCompat.makeSceneTransitionAnimation(this, userIcon, "user_icon").toBundle());
UserInfoActivity.start(Activity, View)
みたいなユーティリティメソッドの中でやってしまうのもありかもしれない。
public static Intent createIntent(Context context) { return new Intent(context, UserInfoActivity.class); } public static void start(Activity activity, View userIcon) { final Intent intent = createIntent(activity.getApplicationContext()); ViewCompat.setTransitionName(userIcon, "user_icon"); ActivityCompat.startActivity(activity, intent, ActivityOptionsCompat.makeSceneTransitionAnimation(activity, userIcon, "user_icon").toBundle()); }