CardViewで背景色を透過度ありの色で設定しようとすると、やりたい内容によってはうまくいかないパターンがあります。何回かそういう場面に遭遇していたのですが、毎回調べている気がするので自分のメモ用にまとめたいと思います。
CardViewの背景透過の問題点
1. シャドー(elevation)を設定している状態で背景色に透過度がある色を設定すると画像のように枠線が表示されてしまう。elevationとかtranslationZの値とか変えると分かるのですが、枠の部分がシャドーを描画するのに使ってそうな感じ。。。
まぁ、背景色を透過して利用するのは想定されてないという感じなのかな?っと。
では、どうやって透過するのか?
解決策としては2パターンかなと思います。- シャドー(elevation)の設定をやめる
- CardView自体のalphaを透過してしまう
1.シャドー(elevation)の設定をやめる
基本的にはこのパターンで済ませた方が楽な気がします。 状況によっては透過でシャドーもつけたいみたいなこともあるとは思うのですが。 一応ダメな書き方を載せておきます。この場合、最初に添付した状態になります。 app:cardBackgroundColorには透過度がある色を設定してます。<androidx.cardview.widget.CardView
android:id="@+id/cardView"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_margin="20dp"
app:cardBackgroundColor="@color/red60"
app:cardCornerRadius="20dp"
app:cardElevation="5dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
<TextView
android:id="@+id/name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_gravity="center"
android:textColor="@color/black"/>
</androidx.cardview.widget.CardView>
cardElevationを0に設定すれば、枠線が表示されることはなくて添付画像のように表示できます。その代わり、elevationが0になるのでシャドーは無くなります。
2.CardView自体のalphaを透過してしまう
CardView自体にalpha設定をすることでも透過は可能です。その場合、透過度合に合わせてシャドーも薄くなります。CardViewの子要素も透過されてしまうので内部に表示したい内容はConstraintLayoutなどで上に重ねるようにしておく必要はあります。
あと、内部に表示する要素はelevation設定した場合はCardView側の値と同じかそれ以上に設定しておく必要もあります。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.cardview.widget.CardView
android:id="@+id/cardView"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_margin="20dp"
android:alpha="0.4"
app:cardBackgroundColor="@color/red"
app:cardCornerRadius="20dp"
app:cardElevation="5dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
</androidx.cardview.widget.CardView>
<TextView
android:id="@+id/name_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_gravity="center"
android:textColor="@color/black"
android:elevation="5dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
まとめ
CardViewの背景透過について、メモ書きレベルですが書いてみました。 角丸がない場合だったら、CardViewのCardBackgroundColorではなくbackgroundColorに設定するだけでもOKなんですけどこの場合はCardViewにしなくてもいいかなーと思って省略しました。 他に解決策あるよなどあれば、教えていただけるとありがたいです。色々と調べているときに合わせて見てたのですが、ViewOutlineProviderを使えば色々なViewで切り抜きができたりするので便利だなと思いました。
CardViewで事足りるパターンが多いのですが、使えそうなタイミングあれば使ってみようかと思います。
参考ページ
https://programming-cafe.com/programming/android-%E3%83%AC%E3%82%A4%E3%82%A2%E3%82%A6%E3%83%88/transparent/
https://stackoverflow.com/questions/28629549/transparent-background-on-cardview-android