<androidx.cardview.widget.CardView
android:id="@+id/actionOneCv"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="0dp"
app:cardElevation="0dp"/>
The above-mentioned writing method is often used to implement a button style.
Problem 1:
If you put it in the bottom position of a dialog as a click button, the dialog background
has rounded corners, but the corner of the displayed button is still a right angle.
Question 2:
At this time, the dialog changes the bg color and finds that the CardView area is still white.
For problem one, of course, you can change CardView to manually set a certain part to be rounded.
But the crux of the two problems is actually the same point, that is:
The default background of CardView with water ripple foreground is white
Solution: Change the default background to transparent, then the background style of the dialog bottom can be displayed.
<androidx.cardview.widget.CardView
android:id="@+id/actionOneCv"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
app:cardBackgroundColor="@color/transparent"
android:foreground="?android:attr/selectableItemBackground"
app:cardCornerRadius="0dp"
app:cardElevation="0dp"/>
You can see the settings here app:cardBackgroundColor="@color/transparent"
.
Here comes the problem, the above method can only set the color, what should I do if I want to set the drawable?
In fact, the solution is very simple: CardView
it is inherited from FrameLayout
, which means that it can wrap content, and wrap other controls (such as ImageView
) inside. The background with drawable can be realized through the wrapped control.
Then there is another problem. Since CardView inherits from FrameLayout, it means that it can set Background. But why is it not displayed after setting it?
This involves the entire View construction process:
public CardView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
//省略属性获取
IMPL.initialize(mCardViewDelegate, context, backgroundColor, radius,
elevation, maxElevation);
}
Initialize the View and enter the construction method, and IMPL.initialize
the method will be called. What is this impl?
private static final CardViewImpl IMPL;
static {
if (Build.VERSION.SDK_INT >= 21) {
IMPL = new CardViewApi21Impl();
} else if (Build.VERSION.SDK_INT >= 17) {
IMPL = new CardViewApi17Impl();
} else {
IMPL = new CardViewBaseImpl();
}
IMPL.initStatic();
}
IMPL is the implementation class of CardView, and different versions have different implementations. Enter CardViewApi21Impl here to see initialize
the implementation.
@Override
public void initialize(CardViewDelegate cardView, Context context,
ColorStateList backgroundColor, float radius, float elevation, float maxElevation) {
final RoundRectDrawable background = new RoundRectDrawable(backgroundColor, radius);
cardView.setCardBackground(background);
View view = cardView.getCardView();
view.setClipToOutline(true);
view.setElevation(elevation);
setMaxElevation(cardView, maxElevation);
}
It can be found that the call is made here cardView.setCardBackground
, and the background is set according to the setting
backgroundColor = a.getColorStateList(R.styleable.CardView_cardBackgroundColor);
Generated by assigning RoundRectDrawable.
cardView.setCardBackground(background);
The CardView in is that CardViewDelegate
it is an interface, so it also depends on its implementation class. In the CardView class can be found:
private final CardViewDelegate mCardViewDelegate = new CardViewDelegate() {
private Drawable mCardBackground;
@Override
public void setCardBackground(Drawable drawable) {
mCardBackground = drawable;
setBackgroundDrawable(drawable);
}
//...
}
And the above setBackgroundDrawable
is to enter the View level.
So far, it is clear that because initialize
it is called after the constructor of the parent class (FrameLayout), the final setting setBackgroundDrawable
will always override the method implementation of the parent class.
In the final analysis, it is a matter of successive coverage of implementation .