いい感じのチュートリアル画面を5分で実装する

## はじめに
こちらは[Android その2 Advent Calendar 2017](https://qiita.com/advent-calendar/2017/android_second)の16日目の記事です。

アプリ初回起動時に表示されるチュートリアル画面、自前で実装しようとすると
「ViewPagerを使って実装する」「下部にIndicatorも表示するには…」などなど何かと手間がかかりますよね。

「チュートリアルは作りたいけどあまり時間と労力を割きたくない」という方のために、簡単にそれっぽいものが実装出来るwelcome-androidというライブラリをご紹介します。

## 概要
本家GitHub: https://github.com/stephentuso/welcome-android

GithubのREADMEはJavaで書かれていますが、今回は勉強も兼ねてKotlinで書いてみます。
5分程度でこういったカッコイイ感じのチュートリアルが実装出来ます(画像は本家のサンプルアニメーション)。
![welcome-android-sample-video.gif](https://qiita-image-store.s3.amazonaws.com/0/68671/f9a95c55-58f5-2475-5816-a875763a9324.gif)

welcome-androidにはデフォルトで用意されている4種類のPageがあり、それらを利用することで手間を大幅に減らすことが出来ます。

ちなみに私の説明が下手くそなせいであまりピンときていない人や、実際に動いているものを見たい人は[本家のデモアプリ](https://play.google.com/store/apps/details?id=com.stephentuso.welcomeexample)も公開されているので見てみて下さい。

## 実装編
それでは具体的な実装方法について説明していきます。
大筋は本家READMEのBasicUsageに従って進めています。

### ライブラリの追加
app/build.gradleに一行追加するだけです。

```groovy:app/build.gradle
compile 'com.stephentuso:welcome:1.4.1'

```
### チュートリアル用Activityを追加
右クリックして[New] => [Activity] => [EmptyActivity]で追加すると楽チンです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/68671/e1123394-f589-4ba9-c646-12475fe8996b.png)

この時layoutファイルは不要になるので、生成しないために[Generate Layout File]のチェックを外しておきます。
また、独自のActivityを継承するので[Backwards Compatibility (AppCompat)]のチェックも外してしまいましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/68671/8675d330-fd06-c62e-2a4d-653bb548811e.png)

AndroidManifest.xmlに自動でActivity定義が追加されるので専用のThemeを設定します。

```xml:AndroidManifest.xml
<activity
    android:name=".TutorialActivity"
    android:theme="@style/WelcomeScreenTheme">
```

生成されたTutorialActivityの継承元をWelcomeActivityに変更し、configurationメソッドをOverrideする。
ついでに表示時に楽をしたいので表示用のメソッドもこちらに定義してしまいました。

```kotlin:TutorialActivity.kt
class TutorialActivity : WelcomeActivity() {

    companion object {
        /**
         * まだ表示していなかったらチュートリアルを表示
         * SharedPreferencesの管理に関しては内部でよしなにやってくれているので普通に呼ぶだけで良い
         */
        fun showIfNeeded(activity: Activity, savedInstanceState: Bundle?) {
            WelcomeHelper(activity, TutorialActivity::class.java).show(savedInstanceState)
        }

        /**
         * 強制的にチュートリアルを表示したい時にはこちらを呼ぶ
         */
        fun showForcibly(activity: Activity) {
            WelcomeHelper(activity, TutorialActivity::class.java).forceShow()
        }
    }

    /**
     * 表示するチュートリアル画面を定義する
     */
    override fun configuration(): WelcomeConfiguration {
        return WelcomeConfiguration.Builder(this)
                .defaultBackgroundColor(BackgroundColor(Color.RED))
                .page(TitlePage(R.mipmap.ic_launcher, "Title"))
                .page(BasicPage(
                        android.R.drawable.ic_delete,
                        "Basic page 1",
                        "hogehoge")
                        .background(BackgroundColor(Color.GREEN)))
                .page(BasicPage(
                        android.R.drawable.ic_btn_speak_now,
                        "Basic page 2",
                        "fugafuga")
                        .background(BackgroundColor(Color.BLUE))
                )
                .swipeToDismiss(true)
                .build()
    }
}
```

あとは、MainActivityのonCreate内から上記で用意したshowIfNeeded()メソッドを呼び出してやるだけです。
コード中のコメントにも書きましたが、チュートリアルを表示した否かの管理はwelcome-android側で管理してくれるので、こちらでSharedPreferencesを別途用意する必要はありません。

たったこれだけの実装でこんな感じのチュートリアルがすぐに出来上がりました。
各画面の背景色の切り替わりも特に実装することなくグラデーション的に切り替わってくれるのはありがたいですね。
![welcome-android-basic.git.gif]
(https://qiita-image-store.s3.amazonaws.com/0/68671/e869d29a-0a36-7624-fc54-80ba359375c4.gif)

### 用意されているPageについて
上記のサンプルではTitlePageとBasePageのみ利用していますが、WelcomeConfiguration.Builder内で設定できるページは全部で下記の4種類です。

#### TitlePage
画像とタイトルのページで、画像に視差効果を適用できます。

```java
TitlePage(@DrawableRes int drawableResId, String title)
```

#### BasicPage
画像、タイトル、説明を含むページ。画像に視差効果を適用することができます。

```java
BasicPage(@DrawableRes int drawableResId, String title, String description)
```

#### ParallaxPage
BasicPageに似ていますが、画像の代わりに視差効果が適用されるレイアウトを引数で受け取ります。
レイアウトの子要素が移動する速度はレイアウト内の位置によって決まり、最初のものが最も遅く、最後は最も早く移動します。

```java
ParallaxPage(@LayoutRes int layoutResId, String title, String description)
```

ちなみにParallaxとは視差という意味らしいです、こんなふうにいい感じに視差効果を付けてくれます。
![ezgif.com-video-to-gif (1).gif](https://qiita-image-store.s3.amazonaws.com/0/68671/f1c9fd03-7d68-6357-7a30-52aa32399a68.gif)

#### FullScreenParallaxPage
ParallaxPageと同じように視差効果が適用されますが、引数で渡すのはレイアウトのみでタイトルや説明が入りません。

```java
FullscreenParallaxPage(@LayoutRes int layoutResId)
```
### カスタマイズ用のページ
FragmentWelcomePageを利用することで自身で定義したFragmentを利用できます。

```java
@Override
protected WelcomeConfiguration configuration() {
    return new WelcomeConfiguration.Builder(this)
            ...
            .page(new FragmentWelcomePage() {
                    @Override
                    protected Fragment fragment() {
                        return new ExampleFragment();
                    }
                }.background(R.color.red_background))
            ...
}
```
### その他の設定項目について
チュートリアルをスキップせずに全部見てもらいたい場合などは、SKIPボタンをレイアウトから消す[^1]ためのフラグもありました。

他にも、デフォルトでも十分それっぽい画面が出来上がるのですが、画面下部のボタンだったり画面のスタイルだったりと色々設定できるものがあるようです。
正直なところここはまだ試すに至っておりません、詳しくは本家のREADMEをご参照下さい。

## おわりに
"welcome-android"という名前が初学者向けコンテンツっぽくも見えるので、それも相まってあまり知られていないのではないかと思っています。
事実「[welcome-android](https://www.google.co.jp/search?q=welcome-android&oq=welcome-android&aqs=chrome..69i57j69i60l2j69i59.2617j0j1&sourceid=chrome&ie=UTF-8)」とGoogle先生に聞くと、1番目に出てくるものの2番目にはwelcome-android関連の情報ではなく[mixiの学習資料](http://mixi-inc.github.io/AndroidTraining/)[^2]が出てしまいますね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/68671/4b41d1fc-6227-34de-f2fd-a8b5af6b72e3.png)

素晴らしいライブラリなのにQiitaに記事が無かったため、皆さんにも知っていただきたく今回のAdventCalendarでご紹介させていただきました。

ちなみにお恥ずかしいお話ですが、[私の個人プロダクトアプリ](https://play.google.com/store/apps/details?id=com.masaibar.nozokimi&referrer=ac_2017_andriod2)にはまだ導入できておりません。
実装は爆速で終わるのですが、エンジニアにとってはそこに載せるアイコン作成がネック[^3]なのです…(;_;)


[^1]: スキップ出来ないチュートリアルというのは、内容によっては途中離脱ユーザーが生まれる可能性もあるため安易に使うべきものでもないと個人的には思っています。

[^2]: 誤解のないように言っておきますと、こちらはこちらで有名かつ素晴らしいドキュメントです。Android始めたばかりのときはめちゃくちゃお世話になりました。また当時はmixi本社でこの資料を基にした初心者向けの勉強会が開かれており、今の自分がいるのはそのお陰と言っても過言ではありません。そして終わってから近くのラーメン凪で焼きラーメンを食べて帰るのが至高でした。

[^3]: どなたかいい感じの画像を作ってくれる心優しいデザイナー様がいらっしゃいましたら是非ご連絡下さい、大したお礼は出来ませんがお肉を焼きに行く位のお礼なら出来ます。