原因是因为只有在 Shape 被标记为 Rounded 时才会发生MaterialCardView
锁定行为,不幸的是,该实现也被默认情况下它自己的组件锁定:clipToOutline
在这里,如果你打开 MaterialCardView.java,你可以找到这段代码:
@Override
public void setShapeAppearanceModel(@NonNull ShapeAppearanceModel shapeAppearanceModel) {
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
setClipToOutline(shapeAppearanceModel.isRoundRect(getBoundsAsRectF()));
}
cardViewHelper.setShapeAppearanceModel(shapeAppearanceModel);
}
如果你更深入, , 的实现isRoundRect
将是这样的:
@RestrictTo(LIBRARY_GROUP)
public boolean isRoundRect(@NonNull RectF bounds) {
boolean hasDefaultEdges =
leftEdge.getClass().equals(EdgeTreatment.class)
&& rightEdge.getClass().equals(EdgeTreatment.class)
&& topEdge.getClass().equals(EdgeTreatment.class)
&& bottomEdge.getClass().equals(EdgeTreatment.class);
float cornerSize = topLeftCornerSize.getCornerSize(bounds);
boolean cornersHaveSameSize =
topRightCornerSize.getCornerSize(bounds) == cornerSize
&& bottomLeftCornerSize.getCornerSize(bounds) == cornerSize
&& bottomRightCornerSize.getCornerSize(bounds) == cornerSize;
boolean hasRoundedCorners =
topRightCorner instanceof RoundedCornerTreatment
&& topLeftCorner instanceof RoundedCornerTreatment
&& bottomRightCorner instanceof RoundedCornerTreatment
&& bottomLeftCorner instanceof RoundedCornerTreatment;
return hasDefaultEdges && cornersHaveSameSize && hasRoundedCorners;
}
如果形状具有相同或所有圆角,则使其返回 true 的条件是。
你不能通过编程设置来欺骗它,card.setClipToOutline(true)
因为它发生在渲染散文之后。
他们这样做的原因是由于设计上的一些限制:
(进一步阅读:https ://github.com/material-components/material-components-android/issues/1950 )
好消息,您可以通过创建自己的MaterialCardView
并覆盖一些这样的实现来解决这个问题:
package com.example.myapp;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import com.google.android.material.card.MaterialCardView;
import com.google.android.material.shape.ShapeAppearancePathProvider;
public class MaskedCardView extends MaterialCardView {
private ShapeAppearancePathProvider pathProvider = new ShapeAppearancePathProvider();
private Path path = new Path();
private RectF rectF = new RectF(0f, 0f, 0f, 0f);
public MaskedCardView(Context context) {
super(context);
}
public MaskedCardView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MaskedCardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.clipPath(path);
super.onDraw(canvas);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
rectF.right = (float) w;
rectF.bottom = (float) h;
pathProvider.calculatePath(getShapeAppearanceModel(), 1f, rectF, path);
super.onSizeChanged(w, h, oldw, oldh);
}
}
我希望它能回答你的问题。