Slide 1

Slide 1 text

角丸?
 それxfermodeで出来るよ
 YUMEMI.apk #1


Slide 2

Slide 2 text

自己紹介
 室山大輔
 株式会社ゆめみ(3月入社)
 アプリエンジニア(Android/Flutter)
 


Slide 3

Slide 3 text

角丸、してますか?


Slide 4

Slide 4 text

角丸
 ● 検索窓
 ● 検索窓の下にあるショートカットボタン
 ● BottomSheetの上部左右隅
 ● スポット一覧のアイコン


Slide 5

Slide 5 text

Shape
 角丸は、Material Designにおける
 Shape(形状)のバリエーションのひとつ
 
 
 https://material.io/design/shape/about-shape.html


Slide 6

Slide 6 text

Androidにおける角丸の実現方法
 ● AndroidXのCardViewを使う
 ● AndroidXのRoundedBitmapDrawableを使う
 ● BitmapShaderとdrawRoundRectの組み合わせでBitmapを加工する
 ● clipRectで描画領域を切り抜く
 ● 画像で表現する
 ● xfermodeにPorterDuff.Mode.CLEARなPorterDuffXfermodeを設定して、角丸矩形の 範囲外を塗りつぶす(消去する) <- コレをご紹介


Slide 7

Slide 7 text

xfermode?


Slide 8

Slide 8 text

xfermode
 Xfermode is the base class for objects that are called to implement custom "transfer-modes" in the drawing pipeline. The static function Create(Modes) can be called to return an instance of any of the predefined subclasses as specified in the Modes enum. When an Xfermode is assigned to an Paint, then objects drawn with that paint have the xfermode applied.
 
 描画パイプラインでカスタムの "転送モード" を実装するために呼び出されるオブジェク トの基底クラス
 https://developer.android.com/reference/android/graphics/Xfermode


Slide 9

Slide 9 text

PorterDuffXfermode
 カスタムの "転送モード" を実装したクラス
 
 1984年に発表された "Compositing Digital Images". の著者 Thomas Porter と Tom Duff にちなんで命名
 
 Androidにおいては、
 本論文で説明されている12のルールを総称して
 アルファ合成モードと呼ぶ
 https://developer.android.com/reference/android/graphics/PorterDuff.Mode#CLEAR


Slide 10

Slide 10 text

PorterDuff.Mode.CLEAR
 Destination pixels covered by the source are cleared to 0. 
 
 PorterDuff.Mode.CLEARを指定したpaintを用意し、角丸矩形の範囲外を指定したpathを 対象に描画すればよさそう
 
 https://developer.android.com/reference/android/graphics/PorterDuff.Mode#CLEAR


Slide 11

Slide 11 text

実践
 PorterDuff.Mode.CLEARなPaint 矩形角丸の外側のPath

Slide 12

Slide 12 text

実践
 わ た し は 指 定 さ れ た P a t h 領 域 の ピ ク セ ル を 消 去 し て う ま れ た 角 丸 V i e w こ ん ご と も よ ろ し く ・ ・ ・

Slide 13

Slide 13 text

実践(コード)
 override fun draw(canvas: Canvas) { super.draw(canvas) canvas.drawPath(clearPath, clearPaint) } /** 塗りつぶし(消去)用の Paintを作成 */ private val clearPaint = Paint().apply { isAntiAlias = true xfermode = PorterDuffXfermode(PorterDuff.Mode.CLEAR) } /** 矩形角丸範囲外を表す Pathを作成 */ private val clearPath get() = Path().apply { // Canvasサイズと縦横幅が同じで、角丸加工した RoundRectを設定 addRoundRect(canvasRect, cornerRadius, cornerRadius, Path.Direction.CW) // RoundRectの範囲外部分を塗りつぶし対象とする fillType = Path.FillType.INVERSE_WINDING } ->


Slide 14

Slide 14 text

実践(結果)


Slide 15

Slide 15 text

よいところ
 ● 画像合成のアプローチで角丸を実現するため、多層に配置されたView群に対して 角丸に加工したい場合に便利
 ● clipRectでもView群を対象に、角丸に加工できるがアンチエイリアスが使えない
 ● PorterDuff.Mode.CLEARではなくPorterDuff.Mode.DST_IN, SRC_INなどを使っても実 現可能(なハズ)


Slide 16

Slide 16 text

まとめ
 デザイン要件がなければ、CardViewを使うのが一番ラク
 ちょっと複雑になりそうならxfermodeを使うと簡単


Slide 17

Slide 17 text

ありがとうございました