CardViewpublic class CardView extends android.widget.FrameLayout implements CardViewDelegateA FrameLayout with a rounded corner background and shadow.
CardView uses elevation property on L for shadows and falls back to a custom shadow
implementation on older platforms.
Due to expensive nature of rounded corner clipping, on platforms before L, CardView does not
clip its children that intersect with rounded corners. Instead, it adds padding to avoid such
intersection (See {@link #setPreventCornerOverlap(boolean)} to change this behavior).
Before L, CardView adds padding to its content and draws shadows to that area. This padding
amount is equal to maxCardElevation + (1 - cos45) * cornerRadius on the sides and
maxCardElevation * 1.5 + (1 - cos45) * cornerRadius on top and bottom.
Since padding is used to offset content for shadows, you cannot set padding on CardView.
Instead,
you can use content padding attributes in XML or {@link #setContentPadding(int, int, int, int)}
in code to set the padding between the edges of the Card and children of CardView.
Note that, if you specify exact dimensions for the CardView, because of the shadows, its content
area will be different between platforms before L and after L. By using api version specific
resource values, you can avoid these changes. Alternatively, If you want CardView to add inner
padding on platforms L and after as well, you can set {@link #setUseCompatPadding(boolean)} to
true .
To change CardView's elevation in a backward compatible way, use
{@link #setCardElevation(float)}. CardView will use elevation API on L and before L, it will
change the shadow size. To avoid moving the View while shadow size is changing, shadow size is
clamped by {@link #getMaxCardElevation()}. If you want to change elevation dynamically, you
should call {@link #setMaxCardElevation(float)} when CardView is initialized. |
Fields Summary |
---|
private static final CardViewImpl | IMPL | private boolean | mCompatPadding | private boolean | mPreventCornerOverlap | private final android.graphics.Rect | mContentPadding | private final android.graphics.Rect | mShadowBounds |
Constructors Summary |
---|
public CardView(android.content.Context context)
super(context);
initialize(context, null, 0);
| public CardView(android.content.Context context, android.util.AttributeSet attrs)
super(context, attrs);
initialize(context, attrs, 0);
| public CardView(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr)
super(context, attrs, defStyleAttr);
initialize(context, attrs, defStyleAttr);
|
Methods Summary |
---|
public float | getCardElevation()Returns the backward compatible elevation of the CardView.
return IMPL.getElevation(this);
| public int | getContentPaddingBottom()Returns the inner padding before the Card's bottom edge
return mContentPadding.bottom;
| public int | getContentPaddingLeft()Returns the inner padding after the Card's left edge
return mContentPadding.left;
| public int | getContentPaddingRight()Returns the inner padding before the Card's right edge
return mContentPadding.right;
| public int | getContentPaddingTop()Returns the inner padding after the Card's top edge
return mContentPadding.top;
| public float | getMaxCardElevation()Returns the backward compatible elevation of the CardView.
return IMPL.getMaxElevation(this);
| public boolean | getPreventCornerOverlap()Returns whether CardView should add extra padding to content to avoid overlaps with rounded
corners on API versions 20 and below.
return mPreventCornerOverlap;
| public float | getRadius()Returns the corner radius of the CardView.
return IMPL.getRadius(this);
| public boolean | getUseCompatPadding()Returns whether CardView will add inner padding on platforms L and after.
return mCompatPadding;
| private void | initialize(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr)
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CardView, defStyleAttr,
R.style.CardView_Light);
int backgroundColor = a.getColor(R.styleable.CardView_cardBackgroundColor, 0);
float radius = a.getDimension(R.styleable.CardView_cardCornerRadius, 0);
float elevation = a.getDimension(R.styleable.CardView_cardElevation, 0);
float maxElevation = a.getDimension(R.styleable.CardView_cardMaxElevation, 0);
mCompatPadding = a.getBoolean(R.styleable.CardView_cardUseCompatPadding, false);
mPreventCornerOverlap = a.getBoolean(R.styleable.CardView_cardPreventCornerOverlap, true);
int defaultPadding = a.getDimensionPixelSize(R.styleable.CardView_contentPadding, 0);
mContentPadding.left = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingLeft,
defaultPadding);
mContentPadding.top = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingTop,
defaultPadding);
mContentPadding.right = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingRight,
defaultPadding);
mContentPadding.bottom = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingBottom,
defaultPadding);
if (elevation > maxElevation) {
maxElevation = elevation;
}
a.recycle();
IMPL.initialize(this, context, backgroundColor, radius, elevation, maxElevation);
| protected void | onMeasure(int widthMeasureSpec, int heightMeasureSpec)
if (IMPL instanceof CardViewApi21 == false) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
switch (widthMode) {
case MeasureSpec.EXACTLY:
case MeasureSpec.AT_MOST:
final int minWidth = (int) Math.ceil(IMPL.getMinWidth(this));
widthMeasureSpec = MeasureSpec.makeMeasureSpec(Math.max(minWidth,
MeasureSpec.getSize(widthMeasureSpec)), widthMode);
break;
}
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
switch (heightMode) {
case MeasureSpec.EXACTLY:
case MeasureSpec.AT_MOST:
final int minHeight = (int) Math.ceil(IMPL.getMinHeight(this));
heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.max(minHeight,
MeasureSpec.getSize(heightMeasureSpec)), heightMode);
break;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
| public void | setCardBackgroundColor(int color)Updates the background color of the CardView
IMPL.setBackgroundColor(this, color);
| public void | setCardElevation(float radius)Updates the backward compatible elevation of the CardView.
IMPL.setElevation(this, radius);
| public void | setContentPadding(int left, int top, int right, int bottom)Sets the padding between the Card's edges and the children of CardView.
Depending on platform version or {@link #getUseCompatPadding()} settings, CardView may
update these values before calling {@link android.view.View#setPadding(int, int, int, int)}.
mContentPadding.set(left, top, right, bottom);
IMPL.updatePadding(this);
| public void | setMaxCardElevation(float radius)Updates the backward compatible elevation of the CardView.
Calling this method has no effect if device OS version is L or newer and
{@link #getUseCompatPadding()} is false .
IMPL.setMaxElevation(this, radius);
| public void | setPadding(int left, int top, int right, int bottom)
// NO OP
| public void | setPaddingRelative(int start, int top, int end, int bottom)
// NO OP
| public void | setPreventCornerOverlap(boolean preventCornerOverlap)On API 20 and before, CardView does not clip the bounds of the Card for the rounded corners.
Instead, it adds padding to content so that it won't overlap with the rounded corners.
You can disable this behavior by setting this field to false .
Setting this value on API 21 and above does not have any effect unless you have enabled
compatibility padding.
if (preventCornerOverlap == mPreventCornerOverlap) {
return;
}
mPreventCornerOverlap = preventCornerOverlap;
IMPL.onPreventCornerOverlapChanged(this);
| public void | setRadius(float radius)Updates the corner radius of the CardView.
IMPL.setRadius(this, radius);
| public void | setShadowPadding(int left, int top, int right, int bottom)Internal method used by CardView implementations to update the padding.
mShadowBounds.set(left, top, right, bottom);
super.setPadding(left + mContentPadding.left, top + mContentPadding.top,
right + mContentPadding.right, bottom + mContentPadding.bottom);
| public void | setUseCompatPadding(boolean useCompatPadding)CardView adds additional padding to draw shadows on platforms before L.
This may cause Cards to have different sizes between L and before L. If you need to align
CardView with other Views, you may need api version specific dimension resources to account
for the changes.
As an alternative, you can set this flag to true and CardView will add the same
padding values on platforms L and after.
Since setting this flag to true adds unnecessary gaps in the UI, default value is
false .
if (mCompatPadding == useCompatPadding) {
return;
}
mCompatPadding = useCompatPadding;
IMPL.onCompatPaddingChanged(this);
|
|