[Android]RecyclerViewで角丸にする方法

RecyclerView で角丸にするには

Button などで角丸にするには android:background に角丸の shape を設定するれば実現できますが、
RecyclerView では中の View がはみ出してしまい、うまくいきません。

そこで、API level 21 から追加された
ViewOutlineProvider  |  Android Developers
を使用します。

Google 公式にサンプルもあります。
GitHub – googlesamples/android-ClippingBasic

実装してみる

Google 公式のサンプルでは、Java で実装されていて RecyclerView も使われていないので、
実際に、kotlin で RecyclerView に 角丸を実装してみました。
ついでに RecyclerView には Groupie を適用して簡単にリスト表示をしています。

実装的には非常に少ないので単純です。

サンプルコードのプロジェクトファイルは下記においてあります。

GitHub – muaaru/testRecyclerViewRoundCorner

ViewOutlineProvider の実装

ViewOutlineProvider を継承したクラスを作成し、getOutline メソッドで角丸にする処理を記述します。
ドキュメントでは、記述されてませんが渡す値は px 単位になります。
なので、各値を dp から px に変換して渡しています。

    class ClipOutlineProvider : ViewOutlineProvider() {
        override fun getOutline(view: View, outline: Outline) {
            val margin = dp2Px(10f, view.context).toInt()
            outline.setRoundRect(
                margin, margin, (view.width - margin), (view.height - margin),
                dp2Px(30f, view.context)
            )
        }

        private fun dp2Px(dp: Float, context: Context): Float {
            val metrics = context.resources.displayMetrics
            return dp * metrics.density
        }
    }

View に角丸を適用

あとは対象の View に下記のように ClipOutlineProvider のインスタンスをセットして clip を有効にすれば適用できます。

    outlineProvider = ClipOutlineProvider()
    clipToOutline = true

まとめ

RecyclerView でも、非常に簡単に角丸が実装できました。
最近だと API level 21 未満に対応するアプリも少ないかと思うので、普通はこれで十分でしょう。