【Android9.0 Pie Java】LINE風にチャット一覧画面→個人チャット画面の遷移アニメーションを実装(サンプルアプリ付)

## 環境
Android9.0 Pie Java

## はじめに
以前投稿した、
[【Android9.0 Pie Java】チャットアプリで横スワイプ→ダイアログ表示→削除を実装する](https://qiita.com/yuta-matsumoto/items/47f7f403a4c379a7a1b3)
の続きになります。

+ チャット一覧の要素を押すと右から左へ覆い被さるようにチャット画面のfragmentが重なる
+ ＜ ボタンを押すと左から右へチャット画面のfragmentが消える

以下のGifのように動作します。
![3731939bc2a2b548bce0dd3ba2b8d615.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285286/fd4a29a4-ee5c-ec83-0df7-69a6daa986d6.gif)


## 完成品URL
全てのコードを載せると大変なことになるので、この記事では省略しています。
チャット画面のlayoutやAdapter等のファイルも含めてDLして動かしてみたい方はこちらからどうぞ！
https://github.com/yuta-matsumoto/chat

## コード
#### ChatListFragment.java
__「チャット一覧の要素を押すと右から左へ覆い被さるようにチャット画面のfragmentが重なる」__実装のコア部分になります。
チャット一覧の各要素のonItemClickの部分をピックアップします。
[ChatListFragment.javaの全文はこちら](https://github.com/yuta-matsumoto/chat/blob/ce20f0149be73bcf6370cd7b648a7bdf72a48991/app/src/main/java/com/example/chat/fragments/ChatListFragment.java)


```java:ChatListFragment.java
        // チャット一覧のアダプター
        final ChatListAdapter adapter = new ChatListAdapter(list) {
            @Override
            public void onItemClick(View view, int pos, List<ChatListRowData> list) {
                // 選択したユーザーの情報を渡す
                ChatFragment fragment = new ChatFragment();
                // fragment間のデータ受け渡しにはBundleが便利
                Bundle args = new Bundle();
                if (args != null) {
                    args.putString("userName", list.get(pos).getName());
                    fragment.setArguments(args);
                }
                // 画面遷移の準備
                FragmentTransaction transaction = getFragmentManager().beginTransaction();
                // 左から右へfragmentを重ねるアニメーション
                transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right); // (1)
                // ChatListFragmentの上にChatFragmentを重ねる
                transaction.add(R.id.mainContainer, fragment, "fragment"); // (2)
                // バックスタックに加える
                transaction.addToBackStack(null);
                transaction.commit();
            }
        };
```
 (1) Fragment間の画面遷移に好きなアニメーションを利用するために、
`FragmentTransaction.setCustomAnimations`を利用しています。
res配下に以下の構成でアニメーションの定義を用意して読み込みます。

>├res/
　　├anim/
　　　　├slide_in_left.xml
　　　　└slide_out_right.xml

```xml:slide_in_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="100%p" android:toXDelta="0"
        android:duration="@android:integer/config_mediumAnimTime"/>
    <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
        android:duration="@android:integer/config_mediumAnimTime" />
</set>
```

```xml:slide_out_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="0" android:toXDelta="100%p"
        android:duration="@android:integer/config_mediumAnimTime"/>
    <alpha android:fromAlpha="1.0" android:toAlpha="1.0"
        android:duration="@android:integer/config_mediumAnimTime" />
</set>
```
(2) `transaction.add`を利用することで、ChatListFragmentの上にChatFragmentを重ねることができます。

#### ChatFragment.java
__「＜ ボタンを押すと左から右へチャット画面のfragmentが消える」__実装のコア部分になります。
チャット一覧の各要素のonViewCreatedの部分をピックアップします。
[ChatFragment.javaの全文はこちら](https://github.com/yuta-matsumoto/chat/blob/ce20f0149be73bcf6370cd7b648a7bdf72a48991/app/src/main/java/com/example/chat/fragments/ChatFragment.java)


```java:ChatFragment.java
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        //・・・省略

        // <ボタンのリスナー
        ImageButton backButton = view.findViewById(R.id.backButton);
        backButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 画面遷移の準備
                FragmentTransaction transaction = getFragmentManager().beginTransaction();
                // 右から左へfragmentが消えるアニメーション
                transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right); // (1)
                // ChatFragmentを削除
                transaction.remove(chatFragment); // (2)
                transaction.commit();
            }
        });
    }
```
(1) ChatListFragmentの記述と同様でOKです。

(2) `transaction.remove`を利用することで、ChatFragmentを削除しています。

以上です。

## 最後に
このアニメーションの動きの再現をするには、どうしても複数のActivityを利用すると上手く決まらず、
Activity自体重いので、__1 Activity + N Fragment__の構成にしました。
最近実機にビルドしてもらったのですが、結構カッコよく動いたので嬉しいです！！