枠ぎりぎりまでImageViewやTextViewが表示される角丸のCardViewを作る
表題のことを仕事でしようと思ったら、かなりぐったりしたので、供養代わりにメモ。
辿りきれてないところもありますが...
内容
CardView
のサポートライブラリについて- 影の設定
- 角丸の設定
ImageView
についてonDraw()
でマスクを抜くsetImageDrawable
で角丸Bitmapを作る
- TextViewなどについて
- 角丸の背景用
shape
を用意する
- 角丸の背景用
CardViewのサポートライブラリについて
一般的なView
の影を表現しようと思ったらそのために shape
要素を用意したり、画像を用意したりと大変です*1が、CardView
はサポートライブラリのものを使う場合、card_view:cardElevation
属性である程度やってくれます*2。
このとき、注意するのは以下の3点です。
- API21以上とそれ以下のバージョンで影の設定方法を揃えるために
card_view:cardUseCompatPadding
をtrue
にする- たぶんこっちの方が指定が1つでいいので楽です
- ただ、影の分marginが必要なので、最終的にちょうどいい間隔にするために
CardView
要素のmarginを調整する必要があります
- API20以下のバージョンで
CardView
に枠線をつけないためcard_view:cardPreventCornerOverlap
をfalse
にする - 影を表示するためには
CardView
要素の周りにmargin
を設定する必要がある*3
上記のようにCardView
を角丸に設定しても、影しか角丸にならない場合があります。
たとえばFrameLayout
等を使ってその中にImageView
やTextView
を置くと、しっかりこれらの子要素の角が出ます。なので、これら子要素も角丸にします。
ImageViewについて
ImageView
についてはデフォルトで角を丸くする設定がありませんでした。まだ開発者になって一週間目ですし、とりあえず、下記の2つのアプローチを実装してみました。
onDraw()でマスクを抜く
API21で動作させたら、Canvas#saveLayer
メソッドで渡すフラグをCanvas.ALL_FLAG
にしないとAPI21だけ、マスク用画像の背景が黒色となって乗算されてしまっていたので、若干慌てました。
setImageDrawable
.. の記事の方で述べられている通り、やや重いらしくてonDraw()
の処理の間0.3sくらいマスク用画像が表示されています。幸いにしてマスク用画像(shape?)は何色でもよいみたいなので、それらしい色にしてごまかして進めています。
画像処理が速いライブラリを使ってonDraw()
でやっていることを入れ替えたら速くなるかもしれないですが、まだ試せていません。
TextViewなどについて
角丸の指定をするcorners
を子要素に持つshape
要素を背景にします。shape
要素については
ShapeDrawable | Android Developers
をご参照ください。
正直、苦戦していた理由とGeny Motion
に見捨てられた低いバージョンのSDKのAndroid Emulator
にインストールが速やかに行えないことと10mmくらい関係ある気がします。
低いバージョンとの互換性についてSuportLibrary
で救われる部分と救われない部分がありますが、使った方が記述が簡単で済むので SupportLibrary
だけは出るたびにチェックしよう、と思ったのでした。