183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar/* 283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * Copyright (C) 2014 The Android Open Source Project 383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * 483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * you may not use this file except in compliance with the License. 683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * You may obtain a copy of the License at 783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * 883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * 1083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * Unless required by applicable law or agreed to in writing, software 1183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 1283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * See the License for the specific language governing permissions and 1483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * limitations under the License. 1583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar */ 1683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 1783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarpackage android.support.v7.widget; 1883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 1983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.content.Context; 2083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.content.res.TypedArray; 2118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyarimport android.graphics.Rect; 2283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.os.Build; 2383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.support.v7.cardview.R; 2483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.util.AttributeSet; 2583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.widget.FrameLayout; 2683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 2783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar/** 2818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * A FrameLayout with a rounded corner background and shadow. 2983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * <p> 3083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * CardView uses <code>elevation</code> property on L for shadows and falls back to a custom shadow 3183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * implementation on older platforms. 3283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * <p> 3318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * Due to expensive nature of rounded corner clipping, on platforms before L, CardView does not 3418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * clip its children that intersect with rounded corners. Instead, it adds padding to avoid such 35c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * intersection (See {@link #setPreventCornerOverlap(boolean)} to change this behavior). 3618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * <p> 3718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * Before L, CardView adds padding to its content and draws shadows to that area. This padding 38bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * amount is equal to <code>maxCardElevation + (1 - cos45) * cornerRadius</code> on the sides and 39bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * <code>maxCardElevation * 1.5 + (1 - cos45) * cornerRadius</code> on top and bottom. 40bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * <p> 41c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * Since padding is used to offset content for shadows, you cannot set padding on CardView. 42c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * Instead, 43bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * you can use content padding attributes in XML or {@link #setContentPadding(int, int, int, int)} 44bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * in code to set the padding between the edges of the Card and children of CardView. 45bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * <p> 46bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * Note that, if you specify exact dimensions for the CardView, because of the shadows, its content 47bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * area will be different between platforms before L and after L. By using api version specific 48bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * resource values, you can avoid these changes. Alternatively, If you want CardView to add inner 49bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * padding on platforms L and after as well, you can set {@link #setUseCompatPadding(boolean)} to 50bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * <code>true</code>. 5118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * <p> 5218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * To change CardView's elevation in a backward compatible way, use 5318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * {@link #setCardElevation(float)}. CardView will use elevation API on L and before L, it will 5418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * change the shadow size. To avoid moving the View while shadow size is changing, shadow size is 5518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * clamped by {@link #getMaxCardElevation()}. If you want to change elevation dynamically, you 5618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * should call {@link #setMaxCardElevation(float)} when CardView is initialized. 5783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * 5883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardBackgroundColor 59bc943f7fa746c149c5e4c3a4eed7febe494d5df5Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardCornerRadius 6018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardElevation 6118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardMaxElevation 62bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardUseCompatPadding 63c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardPreventCornerOverlap 64bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPadding 65bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingLeft 66bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingTop 67bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingRight 68bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingBottom 6983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar */ 7083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarpublic class CardView extends FrameLayout implements CardViewDelegate { 7183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 72bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar private static final CardViewImpl IMPL; 7318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 7483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar static { 75a52784195525cdb1f2bb4d8dde1b8b314f480957Chet Haase if (Build.VERSION.SDK_INT >= 21) { 7683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar IMPL = new CardViewApi21(); 7783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } else if (Build.VERSION.SDK_INT >= 17) { 7883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar IMPL = new CardViewJellybeanMr1(); 7983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } else { 8083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar IMPL = new CardViewEclairMr1(); 8183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } 8283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar IMPL.initStatic(); 8383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } 8483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 85bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar private boolean mCompatPadding; 86bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 87c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar private boolean mPreventCornerOverlap; 88c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar 89bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar private final Rect mContentPadding = new Rect(); 90bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 91bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar private final Rect mShadowBounds = new Rect(); 92bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 93bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 9483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar public CardView(Context context) { 9583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar super(context); 9683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar initialize(context, null, 0); 9783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } 9883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 9983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar public CardView(Context context, AttributeSet attrs) { 10083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar super(context, attrs); 10183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar initialize(context, attrs, 0); 10283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } 10383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 10483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar public CardView(Context context, AttributeSet attrs, int defStyleAttr) { 10583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar super(context, attrs, defStyleAttr); 10683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar initialize(context, attrs, defStyleAttr); 10783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } 10883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 109bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar @Override 110bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar public void setPadding(int left, int top, int right, int bottom) { 111bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar // NO OP 112bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar } 113bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 114bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar public void setPaddingRelative(int start, int top, int end, int bottom) { 115bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar // NO OP 116bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar } 117bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 118bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar /** 119bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * Returns whether CardView will add inner padding on platforms L and after. 120bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * 121bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @return True CardView adds inner padding on platforms L and after to have same dimensions 122bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * with platforms before L. 123bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar */ 124c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar @Override 125bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar public boolean getUseCompatPadding() { 126bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar return mCompatPadding; 127bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar } 128bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 129bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar /** 130bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * CardView adds additional padding to draw shadows on platforms before L. 131bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * <p> 132bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * This may cause Cards to have different sizes between L and before L. If you need to align 133bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * CardView with other Views, you may need api version specific dimension resources to account 134bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * for the changes. 135bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * As an alternative, you can set this flag to <code>true</code> and CardView will add the same 136bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * padding values on platforms L and after. 137bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * <p> 138bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * Since setting this flag to true adds unnecessary gaps in the UI, default value is 139bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * <code>false</code>. 140bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * 141bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @param useCompatPadding True if CardView should add padding for the shadows on platforms L 142bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * and above. 143c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardUseCompatPadding 144bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar */ 145bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar public void setUseCompatPadding(boolean useCompatPadding) { 146bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar if (mCompatPadding == useCompatPadding) { 147bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar return; 148bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar } 149bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar mCompatPadding = useCompatPadding; 150bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar IMPL.onCompatPaddingChanged(this); 151bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar } 152bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 153bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar /** 154bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * Sets the padding between the Card's edges and the children of CardView. 155bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * <p> 156bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * Depending on platform version or {@link #getUseCompatPadding()} settings, CardView may 157bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * update these values before calling {@link android.view.View#setPadding(int, int, int, int)}. 158bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * 159c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * @param left The left padding in pixels 160c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * @param top The top padding in pixels 161c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * @param right The right padding in pixels 162c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * @param bottom The bottom padding in pixels 163bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPadding 164bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingLeft 165bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingTop 166bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingRight 167bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingBottom 168bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar */ 169bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar public void setContentPadding(int left, int top, int right, int bottom) { 170bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar mContentPadding.set(left, top, right, bottom); 171bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar IMPL.updatePadding(this); 172bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar } 17318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 17418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar @Override 17518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 17618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar if (IMPL instanceof CardViewApi21 == false) { 17718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 17818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar switch (widthMode) { 17918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar case MeasureSpec.EXACTLY: 18018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar case MeasureSpec.AT_MOST: 18118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar final int minWidth = (int) Math.ceil(IMPL.getMinWidth(this)); 18218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar widthMeasureSpec = MeasureSpec.makeMeasureSpec(Math.max(minWidth, 18318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar MeasureSpec.getSize(widthMeasureSpec)), widthMode); 18418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar break; 18518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 18618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 18718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 18818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar switch (heightMode) { 18918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar case MeasureSpec.EXACTLY: 19018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar case MeasureSpec.AT_MOST: 19118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar final int minHeight = (int) Math.ceil(IMPL.getMinHeight(this)); 19218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.max(minHeight, 19318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar MeasureSpec.getSize(heightMeasureSpec)), heightMode); 19418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar break; 19518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 19618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar super.onMeasure(widthMeasureSpec, heightMeasureSpec); 19718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } else { 19818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar super.onMeasure(widthMeasureSpec, heightMeasureSpec); 19918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 20018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 20118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 20283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar private void initialize(Context context, AttributeSet attrs, int defStyleAttr) { 20383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CardView, defStyleAttr, 204bc943f7fa746c149c5e4c3a4eed7febe494d5df5Yigit Boyar R.style.CardView_Light); 20583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar int backgroundColor = a.getColor(R.styleable.CardView_cardBackgroundColor, 0); 20683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar float radius = a.getDimension(R.styleable.CardView_cardCornerRadius, 0); 20718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar float elevation = a.getDimension(R.styleable.CardView_cardElevation, 0); 20818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar float maxElevation = a.getDimension(R.styleable.CardView_cardMaxElevation, 0); 209bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar mCompatPadding = a.getBoolean(R.styleable.CardView_cardUseCompatPadding, false); 210c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar mPreventCornerOverlap = a.getBoolean(R.styleable.CardView_cardPreventCornerOverlap, true); 211bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar int defaultPadding = a.getDimensionPixelSize(R.styleable.CardView_contentPadding, 0); 212bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar mContentPadding.left = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingLeft, 213bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar defaultPadding); 214bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar mContentPadding.top = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingTop, 215bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar defaultPadding); 216bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar mContentPadding.right = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingRight, 217bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar defaultPadding); 218bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar mContentPadding.bottom = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingBottom, 219bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar defaultPadding); 22018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar if (elevation > maxElevation) { 22118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar maxElevation = elevation; 22218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 22383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar a.recycle(); 22418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar IMPL.initialize(this, context, backgroundColor, radius, elevation, maxElevation); 22583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } 22683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 22783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar /** 2284eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar * Updates the background color of the CardView 2294eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar * 2304eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar * @param color The new color to set for the card background 2314eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardBackgroundColor 2324eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar */ 2334eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar public void setCardBackgroundColor(int color) { 2344eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar IMPL.setBackgroundColor(this, color); 2354eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar } 2364eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar 2374eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar /** 238bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * Returns the inner padding after the Card's left edge 239bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * 240bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @return the inner padding after the Card's left edge 241bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar */ 242bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar public int getContentPaddingLeft() { 243bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar return mContentPadding.left; 244bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar } 245bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 246bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar /** 247bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * Returns the inner padding before the Card's right edge 248bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * 249bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @return the inner padding before the Card's right edge 250bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar */ 251bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar public int getContentPaddingRight() { 252bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar return mContentPadding.right; 253bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar } 254bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 255bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar /** 256bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * Returns the inner padding after the Card's top edge 257bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * 258bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @return the inner padding after the Card's top edge 259bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar */ 260bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar public int getContentPaddingTop() { 261bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar return mContentPadding.top; 262bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar } 263bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 264bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar /** 265bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * Returns the inner padding before the Card's bottom edge 266bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * 267bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @return the inner padding before the Card's bottom edge 268bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar */ 269bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar public int getContentPaddingBottom() { 270bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar return mContentPadding.bottom; 271bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar } 272bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 273bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar /** 27483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * Updates the corner radius of the CardView. 27583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * 27683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * @param radius The radius in pixels of the corners of the rectangle shape 277bc943f7fa746c149c5e4c3a4eed7febe494d5df5Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardCornerRadius 27883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * @see #setRadius(float) 27983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar */ 28083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar public void setRadius(float radius) { 28183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar IMPL.setRadius(this, radius); 28283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } 28383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar 28483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar /** 28583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * Returns the corner radius of the CardView. 28683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * 28783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * @return Corner radius of the CardView 28883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * @see #getRadius() 28983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar */ 29083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar public float getRadius() { 29183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar return IMPL.getRadius(this); 29283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar } 29318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 29418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar /** 295bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * Internal method used by CardView implementations to update the padding. 296c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * 297bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @hide 298bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar */ 299bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar @Override 300bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar public void setShadowPadding(int left, int top, int right, int bottom) { 301bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar mShadowBounds.set(left, top, right, bottom); 302bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar super.setPadding(left + mContentPadding.left, top + mContentPadding.top, 303bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar right + mContentPadding.right, bottom + mContentPadding.bottom); 304bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar } 305bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 306bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar /** 30718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * Updates the backward compatible elevation of the CardView. 30818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * 30918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @param radius The backward compatible elevation in pixels. 31018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardElevation 31118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @see #getCardElevation() 31218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @see #setMaxCardElevation(float) 31318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar */ 31418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar public void setCardElevation(float radius) { 31518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar IMPL.setElevation(this, radius); 31618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 31718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 31818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar /** 31918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * Returns the backward compatible elevation of the CardView. 32018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * 32118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @return Elevation of the CardView 32218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @see #setCardElevation(float) 32318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @see #getMaxCardElevation() 32418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar */ 32518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar public float getCardElevation() { 32618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar return IMPL.getElevation(this); 32718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 32818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 32918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar /** 33018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * Updates the backward compatible elevation of the CardView. 33118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * <p> 332bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * Calling this method has no effect if device OS version is L or newer and 333bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * {@link #getUseCompatPadding()} is <code>false</code>. 33418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * 33518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @param radius The backward compatible elevation in pixels. 33618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardElevation 33718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @see #setCardElevation(float) 33818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @see #getMaxCardElevation() 33918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar */ 34018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar public void setMaxCardElevation(float radius) { 34118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar IMPL.setMaxElevation(this, radius); 34218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 34318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar 34418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar /** 34518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * Returns the backward compatible elevation of the CardView. 34618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * 34718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @return Elevation of the CardView 34818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @see #setMaxCardElevation(float) 34918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @see #getCardElevation() 35018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar */ 35118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar public float getMaxCardElevation() { 35218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar return IMPL.getMaxElevation(this); 35318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar } 354bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar 355c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar /** 356c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * Returns whether CardView should add extra padding to content to avoid overlaps with rounded 357c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * corners on API versions 20 and below. 358c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * 359c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * @return True if CardView prevents overlaps with rounded corners on platforms before L. 360c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * Default value is <code>true</code>. 361c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar */ 362bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar @Override 363c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar public boolean getPreventCornerOverlap() { 364c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar return mPreventCornerOverlap; 365c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar } 366c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar 367c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar /** 368c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * On API 20 and before, CardView does not clip the bounds of the Card for the rounded corners. 369c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * Instead, it adds padding to content so that it won't overlap with the rounded corners. 370c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * You can disable this behavior by setting this field to <code>false</code>. 371c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * <p> 372c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * Setting this value on API 21 and above does not have any effect unless you have enabled 373c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * compatibility padding. 374c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * 375c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * @param preventCornerOverlap Whether CardView should add extra padding to content to avoid 376c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * overlaps with the CardView corners. 377c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardPreventCornerOverlap 378c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * @see #setUseCompatPadding(boolean) 379c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar */ 380c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar public void setPreventCornerOverlap(boolean preventCornerOverlap) { 381c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar if (preventCornerOverlap == mPreventCornerOverlap) { 382c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar return; 383c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar } 384c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar mPreventCornerOverlap = preventCornerOverlap; 385c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar IMPL.onPreventCornerOverlapChanged(this); 386bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar } 387bc943f7fa746c149c5e4c3a4eed7febe494d5df5Yigit Boyar} 388