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

Androidで丸いCardViewを滑らかにページ遷移させる

More than 1 year has passed since last update.

この記事は Goodpatch Advent Calendar 2018 18日目の記事です。

Google I/O 2018でMaterial Themingが発表され、最近のGoogle製アプリではGoogle独自のMaterial Designを採用したアプリが増えてきましたね。

また、その影響やiOS側のトレンドの変化もあって最近では、様々なアイコンやViewの形状が丸くなってきてたように思います。
そのあたりの考察は別の記事に譲るとして、今回はAndroid開発者として、角が丸めのCardViewを実装した時に困ったことと、その対処法をご紹介します。

cardCornerRadius=16dpのCardView

まずは最近流行りの丸いCardViewを作ります。
分かりやすいようにcardCornerRadiusは16dpにしておきましょう。

<androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:cardCornerRadius="16dp"
            app:cardElevation="1dp">

はい、できました。簡単ですね。

Transition Animationがうまくいかない

このCardViewにShared Elementsを使ったTransition Animationを付けて別のActivityに遷移させてみます。

animation10.gif
分かりやすいようにWindow Animation Scaleはx10です。

アニメーションが始まった瞬間にCardViewでClipされていた四角い画像が表に出てきているのが分かりますか?
Shared Elementを使ったときに遷移中に表示されるViewは遷移後のActivityのViewです。このためClipされていない遷移後のViewがタップ直後に表示されてしまいます。
これではせっかくのCardViewが少し残念です。

Transition中のViewのサイズに合わせてClipするradiusを変化させる

今回はCardViewの中に使うViewをpathでclipすることで滑らかにアニメーションさせるようにしてみました。
Transition Animation時にViewのサイズが変わるたびにonDrawが呼びだされるため、その時のViewの幅に合わせて少しずつRadiusが変化するようにします。

private val rootWidth = resources.displayMetrics.widthPixels
private val cornerRadius: Float = resources.getDimension(R.dimen.card_corner_radius)
private val cardSideMargin: Float = resources.getDimension(R.dimen.card_side_margin) * 2

override fun onDraw(canvas: Canvas) {
        // viewの幅に合わせてcornerRadiusを変化させる
        val radius = Math.min(cornerRadius, cornerRadius * ((rootWidth - this.width) / cardSideMargin))
        clipPath.reset()
        clipRectF.set(canvas.clipBounds)
        clipPath.addRoundRect(clipRectF, radius, radius, Path.Direction.CW)
        canvas.clipPath(clipPath)
        super.onDraw(canvas)
}

animation11.gif
いい感じになりました。(個人の感想です。

今回のすべてのサンプルはこちらです。
ymegane/CardAnimationSample | GitHub

これで週末は心置きなく映画館に行けそうです。
みなさんよいクリスマスを。

y_megane
主にAndroidアプリをやってます。たまにiOSも。
https://airhole.ymegane.org/
goodpatch
Goodpatch(株式会社グッドパッチ)は東京、ベルリン、台北にあるWeb / iOS / AndroidなどマルチデバイスアプリケーションのUIデザイン会社です。サービスやプロダクトの企画設計から関わりコンセプトメイキング、UX設計、プロトタイピング、UIデザイン、実装までワンストップで提供しています。
https://goodpatch.com/
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
ユーザーは見つかりませんでした