イースターエッグ機能（隠れ処理機能）の実装してみた

##はじめに
「イースターエッグってなんやねん。」

って初めてこの単語に出会ったときに思いました。
そもそもこの単語と出会ったのは、業務で

**「デフォルトでは何も表示されてないけど、この部分を押すとある単語が表示されるようにしてくれ〜」**

というお達しを受けたのがきっかけでした。

「簡単やん」

そう思いました。
TextViewを用意してvisibility属性をView.INVISIBLEに設定して、そのTextViewにクリックイベントのonClick属性を紐付けてそのメソッドでvisibility属性をView.VISIBLEに再設定する。

これだけでできると思っていました。

ちなみに、View.INVISIBLEとView.GONEの違いはなんとなくしかわかっていませんでした。なので、次にまとめます。

| Constant  | Description |
|:----------|:------------|
| visible   | 画面に表示される。デフォルト値。 |
| invisible | 画面に表示はされないが、レイアウト中には考慮される（スペースは残される）。 |
| gone      | ビューが追加されていないかのように完全に非表示になる。 |
出典: [Android Developers](https://developer.android.com/reference/android/view/View.html#attr_android:visibility)

なるほど、やはりINVISIBLEで良さそうだ。
以下のコードで実装してみました。
（※コードは分かる範囲で大いに割愛しています。）

```kotlin
<layout>
    ...
    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/easter_egg"
　　　　 ...
        android:text="イースターエッグ発動！！！"
        android:visibility="@{vm.isShown.booleanValue() ? View.VISIBLE : View.INVISIBLE}"
        android:onClick="@{() -> vm.tapped()}" />
</layout>

class MainViewModel {
    var isShown = MutableLiveData(false)
    ...
    fun tapped() {
        isShown.value = !isShown.value!!
    }
}
```
しかし！！！

**「クリックできんがや！！！」**

やはり**INVISIBLEではクリックイベントは取得できないのか・・・**と思い、
[ android invisible clickable ] などの検索ワードで調べてみました。

すると、[stack over flow](https://stackoverflow.com/questions/6851644/setting-android-button-invisible-but-still-having-an-onclick-listener-attached/6851688)で「Easter egg」の単語に出会いました。調べました。

## イースターエッグとは

> イースター・エッグ（Easter egg）とは、コンピュータのソフトウェア・書籍・CDなどに隠されていて、本来の機能・目的とは無関係であるメッセージや画面の総称である。
出典: [Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%BC%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%BB%E3%82%A8%E3%83%83%E3%82%B0_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF))

ふむ。
こういう隠れ機能のことをイースターエッグっていうのか。

ということで、こんな経緯で出会いました。

さて、まだ問題は解決していません。
それから、先程のキーワードで調べてみたところ、様々な解決策が見つかりました。

どうやら、同一のViewにonClick属性とvisibility属性を設定している場合、visibility属性がView.INVISIBLEに設定しているとクリックイベントは発動しないことがわかった。

じゃあ、どうするか。

**解決策**
(1)親レイヤにonclick属性を設定し、その子レイヤにvisibility属性を設定する。
(2)visibility属性を使用せずに、テキストの色やボタンの背景などを透明にする。

この２パターンで解決するはず！！！

いざ実装！
## (1)親レイヤにonclick属性を設定し、その子レイヤにvisibility属性を設定する。

```kotlin
<layout>
    ...
    <androidx.constraintlayout.widget.ConstraintLayout
        ...
        android:onClick="@{() -> vm.tapped()}" >

        <androidx.appcompat.widget.AppCompatTextView
            android:id="@+id/easter_egg"
　　　　     ...
            android:text="イースターエッグ発動！！！"
            android:visibility="@{vm.isShown.booleanValue() ? View.VISIBLE : View.INVISIBLE}" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

class MainViewModel {
    var isShown = MutableLiveData(false)
    ...
    fun tapped() {
        isShown.value = !isShown.value!!
    }
}
```

## (2)visibility属性を使用せずに、テキストの色やボタンの背景などを透明にする。

```kotlin
<layout>
    ...
    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/easter_egg"
　　　　 ...
        android:text="イースターエッグ発動！！！"
        android:textColor="@{vm.isShown.booleanValue() ? @android:color/black : @android:color/transparent}"
        android:onClick="@{() -> vm.tapped()}" />
</layout>

class MainViewModel {
    var isShown = MutableLiveData(false)
    ...
    fun tapped() {
        isShown.value = !isShown.value!!
    }
}
```
![easter_egg_gif4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306161/7f703f94-0f51-74f2-bd0b-2fdae6cb98fa.gif)

めでたし。

##おわりに
**同一のViewにonClick属性とvisibility属性を設定している場合、visibility属性をView.INVISIBLEに設定しているとクリックイベントは発動しない!!!**ので工夫が必要でした。