AndroidでViewをくるっと裏返す【ワクワクさん】

Gmailアプリなんかでよく見るくるっと裏返るViewを実装していこうという回です。

f:id:aosa4054:20190223001222g:plain
Aと書いてある丸いViewが裏返ってます

どうやったか

コードを示す前に簡単な指針を説明したいと思います。

  • 裏返る前のViewと裏返った後のViewを同じ位置に用意する
  • 裏返る前のViewはvisibleに、裏返った後のViewはgoneにしておく
  • Viewの横幅が1から0になるアニメーションと、0から1になるアニメーションを用意する
  • 裏返る前のViewのonClickで
    • 横幅が0になるアニメーションを行い、visibilityをgoneにする
    • 裏返った後のViewに横幅が1になるアニメーションを行い、visibleにする。

といった感じです。 裏返る前とあとで同じ形のViewを使っていれば、これでいい感じに裏返ってるように見えるかと思います。

力技感。

実装

Animation

turn_over_off.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:duration="150"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="0"
        android:toYScale="1.0"
        android:interpolator="@android:anim/accelerate_interpolator"/>
</set>

turn_over_on.xml

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:startOffset="150">
    <scale
        android:duration="150"
        android:fromXScale="0"
        android:fromYScale="1.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.0"
        android:toYScale="1.0"
        android:interpolator="@android:anim/accelerate_interpolator"/>
</set>

Kotlin

fun View.disappear(){
    val offAnim = AnimationUtils.loadAnimation(activity, R.anim.turn_over_off)
    this.startAnimation(offAnim)
    this.visibility = View.GONE
}
fun View.appear(){
    val onAnim = AnimationUtils.loadAnimation(activity, R.anim.turn_over_on)
    this.startAnimation(onAnim)
    this.visibility = View.VISIBLE
}

//view1が裏返す前のView、view2が裏返った後のViewです。
//xmlなどで最初にview2のvisibilityをgoneにしておきます。

view1.setOnClickListener {
    view1.disappear()
    view2.appear()
}

view2.setOnClickListener {
    view2.disappear()
    view1.appear()
}

だいたい見たまんまです。
先ほど示した指針をそのままコードにした感じです。

View.disappear()View.appear()という拡張関数を作って可読性をあげようとあがいています。

注意など

  • アニメーションファイルにfillAfterfillBeforeを設定するとバグる(書いた通りの挙動をしてくれない)ので書かないようにしましょう

  • turn_over_on.xmlに設定しているandroid:startOffsetではアニメーションが開始するまでに待機する時間を設定できます。
    これを設定しないとoffAnimが始まった直後にonAnimが始まってカオスな見た目になります。(Coroutines使ってdelay()とかでも良いかも)

  • turn_over_off.xmlturn_over_on.xmlのdurationを合わせる必要はありませんが、turn_over_off.xmlのdurationと turn_over_on.xmlのstartOffsetは同じにすると良いと思います。

  • マジで個人の感想ですがアニメーションのdurationは150がちょうどいいんじゃないかと感じました。

ワクワクさん

YouTuberデビューしたようですね。 まだ見てませんが興味はあります。