Help us understand the problem. What is going on with this article?

画面遷移を滑らかに (Activity Transitions)

More than 3 years have passed since last update.

今更ながらActivity Transitions

Android Developersを読みながら,Activity Transitionsを実装しました.
ezgif.com-optimize.gif
やったことを書きます.

手順

やったことは大きく分けて3つでした.

  1. Activity Transitions用のテーマの作成
  2. 2つのActivityで共有するViewを決める
  3. startActivityをActivity Transitons用に書き換える

ActivityTransitions用のテーマの作成

今のテーマはこうなってます.

res/values/styles.xml
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/primary</item>
    <!-- 省略 -->
</style>

それをこうしておきます.

res/values/styles.xml
<style name="AppTheme" parent="AppTheme.Base" />

<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/primary</item>
    <!-- 省略 -->
</style>

AppThemeにあった内容を,新しく作ったAppTheme.Baseに移しました.

ActivityTransitionsに必要な属性は,minSdkVersionが21以上でないと使えません.
minSdkVersionは変えたくないので,res/values-v21/styles.xmlで属性の追加を行います.

res/values-v21/styles.xmlを作成し,以下の内容を書きます.

res/values-v21/styles.xml
   <style name="AppTheme" parent="AppTheme.Base">    <!-- AppTheme.Baseを継承 -->
        <item name="android:windowContentTransitions">true</item>
        <item name="android:windowAllowEnterTransitionOverlap">true</item>
        <item name="android:windowAllowReturnTransitionOverlap">true</item>
        <item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
        <item name="android:windowSharedElementExitTransition">@android:transition/move</item>
    </style>

AppTheme.Baseを作ったのは,ここで余計なコードを書かないためです.

そして,遷移を行う2つのアクティビティImageListActivityImageDetailActivityに,
このテーマを適用します.

AndroidManifest.xml
<activity
    android:name=".ui.ImageListActivity"
    android:theme="@style/AppTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name=".ui.ImageDetailActivity"
    android:theme="@style/AppTheme" />

これで,テーマの設定は完了です.

2つのActivityで共有するViewを決める

リストから詳細画面への遷移なので,クリックした画像(ImageView)を共有することにします.
変更するのは,共有するViewを定義している2つのレイアウトファイルです.

こちらも,minSdkVersionが21より小さいアプリでも対応できるよう,
res/layout-v21というディレクトリを作って,そちらに変更を行ったファイルを置いていきます.

具体的には,
res/layout/row_list.xmlは,res/layout-v21/row_list.xmlにコピーして,res/layout-v21/row_list.xmlの方で変更を行います.

では,res/layout-v21にコピーした,リストのlayout定義ファイルのImageViewに変更を加えます.
ListViewのArrayAdapterの中で,このように使っているレイアウトファイルのことです.
convertView = mInflater.inflate(R.layout.row_list, parent, false);

res/layout-v21/row_list.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/row_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/row_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:transitionName="@string/trans_name" />    <!-- new line -->

    <!-- 省略 -->

android:transitionName="@string/trans_name"を共有したいImageViewの属性に追加しました.
@string/trans_nameは下のように定義した,ただの文字列です.

res/values/strings.xml
<string name="trans_name">list_to_detail</string>

詳細画面のレイアウトファイルでも同じことをします.

res/layout-v21/activity_detail.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/detail_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/detail_image"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:transitionName="@string/trans_name" />    <!-- new line -->

    <!-- 省略 -->

android:transitionName="@string/trans_name"を共有したいImageViewの属性に追加しました.

このandroid:transitionNameによって,
リストの画像は詳細画面のどこに移動すれば良いのか分かるようになります.

あとは,startActivityの部分を書き換えれば完成です.

startActivityをActivityTransitions用に書き換える

リストのクリックに合わせて詳細画面に行く部分はこんな感じでした.

ImageListActivity.java
mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        ListItem item = mAdapter.getItem(position);
        Intent intent = new Intent(mActivity, ImageDetailActivity.class);
        intent.putExtra(ImageDetailActivity.EXTRA_CONTENT, item.toJson());
        startActivity(intent);
    }
});

それがこうなります.

ImageListActivity.java
mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
         ActivityOptionsCompat options = ActivityOptionsCompat.makeSceneTransitionAnimation(
             mActivity,
             view.findViewById(R.id.row_image),
             getString(R.string.trans_name) );
         ListItem item = mAdapter.getItem(position);
         Intent intent = new Intent(mActivity, ImageDetailActivity.class);
         intent.putExtra(ImageDetailActivity.EXTRA_CONTENT, item.toJson());
         ActivityCompat.startActivity(activity, intent, options.toBundle());
    }
});

これで完成です.

最後に

GitHubにあった,MaterialEverywhereMaterialDesignSampleが,とても参考になりました.

参考URL

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした