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;
20d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikasimport android.content.res.ColorStateList;
2183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.content.res.TypedArray;
22dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banesimport android.graphics.Color;
2318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyarimport android.graphics.Rect;
24ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banesimport android.graphics.drawable.Drawable;
2583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.os.Build;
2686223c8f397daa57fff72d6bd5cf10ceeb74d40eChris Banesimport android.support.annotation.ColorInt;
27d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikasimport android.support.annotation.Nullable;
2883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.support.v7.cardview.R;
2983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.util.AttributeSet;
30ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banesimport android.view.View;
3183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyarimport android.widget.FrameLayout;
3283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
3383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar/**
3418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * A FrameLayout with a rounded corner background and shadow.
3583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * <p>
36e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * CardView uses <code>elevation</code> property on Lollipop for shadows and falls back to a
37e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * custom emulated shadow implementation on older platforms.
3883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * <p>
39e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * Due to expensive nature of rounded corner clipping, on platforms before Lollipop, CardView does
40e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * not clip its children that intersect with rounded corners. Instead, it adds padding to avoid such
41c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * intersection (See {@link #setPreventCornerOverlap(boolean)} to change this behavior).
4218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * <p>
43e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * Before Lollipop, CardView adds padding to its content and draws shadows to that area. This
44e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * padding amount is equal to <code>maxCardElevation + (1 - cos45) * cornerRadius</code> on the
45e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * sides and <code>maxCardElevation * 1.5 + (1 - cos45) * cornerRadius</code> on top and bottom.
46bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * <p>
47c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * Since padding is used to offset content for shadows, you cannot set padding on CardView.
48e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * Instead, you can use content padding attributes in XML or
49e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * {@link #setContentPadding(int, int, int, int)} in code to set the padding between the edges of
50e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * the CardView and children of CardView.
51bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * <p>
52bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * Note that, if you specify exact dimensions for the CardView, because of the shadows, its content
53e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * area will be different between platforms before Lollipop and after Lollipop. By using api version
54e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * specific resource values, you can avoid these changes. Alternatively, If you want CardView to add
55e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * inner padding on platforms Lollipop and after as well, you can call
56e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * {@link #setUseCompatPadding(boolean)} and pass <code>true</code>.
5718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * <p>
5818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * To change CardView's elevation in a backward compatible way, use
59e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * {@link #setCardElevation(float)}. CardView will use elevation API on Lollipop and before
60e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * Lollipop, it will change the shadow size. To avoid moving the View while shadow size is changing,
61e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * shadow size is clamped by {@link #getMaxCardElevation()}. If you want to change elevation
62e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov * dynamically, you should call {@link #setMaxCardElevation(float)} when CardView is initialized.
6383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar *
6483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardBackgroundColor
65bc943f7fa746c149c5e4c3a4eed7febe494d5df5Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardCornerRadius
6618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardElevation
6718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardMaxElevation
68bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardUseCompatPadding
69c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_cardPreventCornerOverlap
70bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPadding
71bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingLeft
72bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingTop
73bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingRight
74bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingBottom
7583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar */
76ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banespublic class CardView extends FrameLayout {
7783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
78dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes    private static final int[] COLOR_BACKGROUND_ATTR = {android.R.attr.colorBackground};
79bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    private static final CardViewImpl IMPL;
8018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar
8183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    static {
82a52784195525cdb1f2bb4d8dde1b8b314f480957Chet Haase        if (Build.VERSION.SDK_INT >= 21) {
83b7adf5d2ae19bc616c2d040a667ac1de3769f423Aurimas Liutikas            IMPL = new CardViewApi21Impl();
8483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        } else if (Build.VERSION.SDK_INT >= 17) {
85b7adf5d2ae19bc616c2d040a667ac1de3769f423Aurimas Liutikas            IMPL = new CardViewApi17Impl();
8683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        } else {
87b7adf5d2ae19bc616c2d040a667ac1de3769f423Aurimas Liutikas            IMPL = new CardViewBaseImpl();
8883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        }
8983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        IMPL.initStatic();
9083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
9183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
92bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    private boolean mCompatPadding;
93bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
94c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar    private boolean mPreventCornerOverlap;
95c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar
9672aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar    /**
9772aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar     * CardView requires to have a particular minimum size to draw shadows before API 21. If
9872aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar     * developer also sets min width/height, they might be overridden.
9972aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar     *
10072aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar     * CardView works around this issue by recording user given parameters and using an internal
10172aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar     * method to set them.
10272aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar     */
103412e1117ba871f268593f30d8c849624eb5cf4deAurimas Liutikas    int mUserSetMinWidth, mUserSetMinHeight;
10472aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar
105412e1117ba871f268593f30d8c849624eb5cf4deAurimas Liutikas    final Rect mContentPadding = new Rect();
106bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
107412e1117ba871f268593f30d8c849624eb5cf4deAurimas Liutikas    final Rect mShadowBounds = new Rect();
108bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
10983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    public CardView(Context context) {
11083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        super(context);
11183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        initialize(context, null, 0);
11283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
11383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
11483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    public CardView(Context context, AttributeSet attrs) {
11583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        super(context, attrs);
11683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        initialize(context, attrs, 0);
11783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
11883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
11983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    public CardView(Context context, AttributeSet attrs, int defStyleAttr) {
12083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        super(context, attrs, defStyleAttr);
12183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        initialize(context, attrs, defStyleAttr);
12283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
12383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
124bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    @Override
125bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    public void setPadding(int left, int top, int right, int bottom) {
126bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        // NO OP
127bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
128bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
129e2104f4b5c8e3ad63570306a25e61502dfe4c418Aurimas Liutikas    @Override
130bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    public void setPaddingRelative(int start, int top, int end, int bottom) {
131bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        // NO OP
132bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
133bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
134bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    /**
135e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * Returns whether CardView will add inner padding on platforms Lollipop and after.
136bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     *
137e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * @return <code>true</code> if CardView adds inner padding on platforms Lollipop and after to
138e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * have same dimensions with platforms before Lollipop.
139bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     */
140bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    public boolean getUseCompatPadding() {
141bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        return mCompatPadding;
142bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
143bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
144bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    /**
145e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * CardView adds additional padding to draw shadows on platforms before Lollipop.
146bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * <p>
147e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * This may cause Cards to have different sizes between Lollipop and before Lollipop. If you
148e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * need to align CardView with other Views, you may need api version specific dimension
149e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * resources to account for the changes.
150bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * As an alternative, you can set this flag to <code>true</code> and CardView will add the same
151e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * padding values on platforms Lollipop and after.
152bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * <p>
153bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * Since setting this flag to true adds unnecessary gaps in the UI, default value is
154bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * <code>false</code>.
155bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     *
156e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * @param useCompatPadding <code>true></code> if CardView should add padding for the shadows on
157e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     *      platforms Lollipop and above.
158c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     * @attr ref android.support.v7.cardview.R.styleable#CardView_cardUseCompatPadding
159bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     */
160bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    public void setUseCompatPadding(boolean useCompatPadding) {
161ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        if (mCompatPadding != useCompatPadding) {
162ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            mCompatPadding = useCompatPadding;
163ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            IMPL.onCompatPaddingChanged(mCardViewDelegate);
164bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        }
165bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
166bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
167bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    /**
168bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * Sets the padding between the Card's edges and the children of CardView.
169bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * <p>
170bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * Depending on platform version or {@link #getUseCompatPadding()} settings, CardView may
171bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * update these values before calling {@link android.view.View#setPadding(int, int, int, int)}.
172bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     *
173c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     * @param left   The left padding in pixels
174c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     * @param top    The top padding in pixels
175c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     * @param right  The right padding in pixels
176c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     * @param bottom The bottom padding in pixels
177bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPadding
178bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingLeft
179bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingTop
180bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingRight
181bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * @attr ref android.support.v7.cardview.R.styleable#CardView_contentPaddingBottom
182bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     */
183bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    public void setContentPadding(int left, int top, int right, int bottom) {
184bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        mContentPadding.set(left, top, right, bottom);
185ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        IMPL.updatePadding(mCardViewDelegate);
186bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
18718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar
18818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar    @Override
18918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
190b7adf5d2ae19bc616c2d040a667ac1de3769f423Aurimas Liutikas        if (!(IMPL instanceof CardViewApi21Impl)) {
19118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar            final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
19218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar            switch (widthMode) {
19318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar                case MeasureSpec.EXACTLY:
19418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar                case MeasureSpec.AT_MOST:
195ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes                    final int minWidth = (int) Math.ceil(IMPL.getMinWidth(mCardViewDelegate));
19618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar                    widthMeasureSpec = MeasureSpec.makeMeasureSpec(Math.max(minWidth,
19718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar                            MeasureSpec.getSize(widthMeasureSpec)), widthMode);
19818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar                    break;
19918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar            }
20018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar
20118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar            final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
20218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar            switch (heightMode) {
20318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar                case MeasureSpec.EXACTLY:
20418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar                case MeasureSpec.AT_MOST:
205ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes                    final int minHeight = (int) Math.ceil(IMPL.getMinHeight(mCardViewDelegate));
20618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.max(minHeight,
20718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar                            MeasureSpec.getSize(heightMeasureSpec)), heightMode);
20818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar                    break;
20918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar            }
21018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
21118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar        } else {
21218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
21318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar        }
21418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar    }
21518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar
21683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    private void initialize(Context context, AttributeSet attrs, int defStyleAttr) {
21783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CardView, defStyleAttr,
218dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes                R.style.CardView);
219d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas        ColorStateList backgroundColor;
220dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes        if (a.hasValue(R.styleable.CardView_cardBackgroundColor)) {
221d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas            backgroundColor = a.getColorStateList(R.styleable.CardView_cardBackgroundColor);
222dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes        } else {
223dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes            // There isn't one set, so we'll compute one based on the theme
224dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes            final TypedArray aa = getContext().obtainStyledAttributes(COLOR_BACKGROUND_ATTR);
225dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes            final int themeColorBackground = aa.getColor(0, 0);
226dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes            aa.recycle();
227dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes
228dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes            // If the theme colorBackground is light, use our own light color, otherwise dark
229dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes            final float[] hsv = new float[3];
230dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes            Color.colorToHSV(themeColorBackground, hsv);
231d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas            backgroundColor = ColorStateList.valueOf(hsv[2] > 0.5f
232dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes                    ? getResources().getColor(R.color.cardview_light_background)
233d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas                    : getResources().getColor(R.color.cardview_dark_background));
234dba32f5fecbcd344460fc8cbcfb82ae4fcd0ba69Chris Banes        }
23583b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        float radius = a.getDimension(R.styleable.CardView_cardCornerRadius, 0);
23618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar        float elevation = a.getDimension(R.styleable.CardView_cardElevation, 0);
23718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar        float maxElevation = a.getDimension(R.styleable.CardView_cardMaxElevation, 0);
238bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        mCompatPadding = a.getBoolean(R.styleable.CardView_cardUseCompatPadding, false);
239c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar        mPreventCornerOverlap = a.getBoolean(R.styleable.CardView_cardPreventCornerOverlap, true);
240bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        int defaultPadding = a.getDimensionPixelSize(R.styleable.CardView_contentPadding, 0);
241bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        mContentPadding.left = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingLeft,
242bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar                defaultPadding);
243bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        mContentPadding.top = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingTop,
244bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar                defaultPadding);
245bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        mContentPadding.right = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingRight,
246bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar                defaultPadding);
247bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        mContentPadding.bottom = a.getDimensionPixelSize(R.styleable.CardView_contentPaddingBottom,
248bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar                defaultPadding);
24918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar        if (elevation > maxElevation) {
25018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar            maxElevation = elevation;
25118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar        }
25272aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar        mUserSetMinWidth = a.getDimensionPixelSize(R.styleable.CardView_android_minWidth, 0);
25372aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar        mUserSetMinHeight = a.getDimensionPixelSize(R.styleable.CardView_android_minHeight, 0);
25483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar        a.recycle();
25572aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar
256ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        IMPL.initialize(mCardViewDelegate, context, backgroundColor, radius,
257ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes                elevation, maxElevation);
25883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
25983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
26072aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar    @Override
26172aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar    public void setMinimumWidth(int minWidth) {
26272aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar        mUserSetMinWidth = minWidth;
26372aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar        super.setMinimumWidth(minWidth);
26472aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar    }
26572aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar
26672aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar    @Override
26772aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar    public void setMinimumHeight(int minHeight) {
26872aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar        mUserSetMinHeight = minHeight;
26972aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar        super.setMinimumHeight(minHeight);
27072aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar    }
27172aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar
27272aedb5058595ed481c93f78deb9dc1b00fecf2aYigit Boyar    /**
2734eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar     * Updates the background color of the CardView
2744eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar     *
2754eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar     * @param color The new color to set for the card background
2764eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar     * @attr ref android.support.v7.cardview.R.styleable#CardView_cardBackgroundColor
2774eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar     */
27886223c8f397daa57fff72d6bd5cf10ceeb74d40eChris Banes    public void setCardBackgroundColor(@ColorInt int color) {
27986223c8f397daa57fff72d6bd5cf10ceeb74d40eChris Banes        IMPL.setBackgroundColor(mCardViewDelegate, ColorStateList.valueOf(color));
280d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas    }
281d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas
282d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas    /**
283d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas     * Updates the background ColorStateList of the CardView
284d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas     *
285d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas     * @param color The new ColorStateList to set for the card background
286d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas     * @attr ref android.support.v7.cardview.R.styleable#CardView_cardBackgroundColor
287d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas     */
288d2c60296856244030e9a92ef3065d3884ac67527Aurimas Liutikas    public void setCardBackgroundColor(@Nullable ColorStateList color) {
289ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        IMPL.setBackgroundColor(mCardViewDelegate, color);
2904eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar    }
2914eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar
2924eb77f0ed24a9d300f7d12959de8cf7efd837e2fYigit Boyar    /**
293e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikas     * Returns the background color state list of the CardView.
294e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikas     *
295e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikas     * @return The background color state list of the CardView.
296e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikas     */
297e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikas    public ColorStateList getCardBackgroundColor() {
298e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikas        return IMPL.getBackgroundColor(mCardViewDelegate);
299e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikas    }
300e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikas
301e7c701f05b4f6afa2913c3743638d7b25b96df83Aurimas Liutikas    /**
302bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * Returns the inner padding after the Card's left edge
303bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     *
304bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * @return the inner padding after the Card's left edge
305bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     */
306bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    public int getContentPaddingLeft() {
307bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        return mContentPadding.left;
308bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
309bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
310bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    /**
311bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * Returns the inner padding before the Card's right edge
312bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     *
313bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * @return the inner padding before the Card's right edge
314bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     */
315bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    public int getContentPaddingRight() {
316bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        return mContentPadding.right;
317bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
318bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
319bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    /**
320bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * Returns the inner padding after the Card's top edge
321bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     *
322bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * @return the inner padding after the Card's top edge
323bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     */
324bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    public int getContentPaddingTop() {
325bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        return mContentPadding.top;
326bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
327bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
328bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    /**
329bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * Returns the inner padding before the Card's bottom edge
330bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     *
331bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * @return the inner padding before the Card's bottom edge
332bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     */
333bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    public int getContentPaddingBottom() {
334bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar        return mContentPadding.bottom;
335bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
336bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
337bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    /**
33883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar     * Updates the corner radius of the CardView.
33983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar     *
34083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar     * @param radius The radius in pixels of the corners of the rectangle shape
341bc943f7fa746c149c5e4c3a4eed7febe494d5df5Yigit Boyar     * @attr ref android.support.v7.cardview.R.styleable#CardView_cardCornerRadius
34283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar     * @see #setRadius(float)
34383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar     */
34483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    public void setRadius(float radius) {
345ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        IMPL.setRadius(mCardViewDelegate, radius);
34683b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    }
34783b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar
34883b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    /**
34983b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar     * Returns the corner radius of the CardView.
35083b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar     *
35183b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar     * @return Corner radius of the CardView
35283b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar     * @see #getRadius()
35383b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar     */
35483b8526436ba2e564dff99ec4c6cf46fabfdf22eYigit Boyar    public float getRadius() {
355ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        return IMPL.getRadius(mCardViewDelegate);
356bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
357bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
358bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    /**
35918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     * Updates the backward compatible elevation of the CardView.
36018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     *
361e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * @param elevation The backward compatible elevation in pixels.
36218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     * @attr ref android.support.v7.cardview.R.styleable#CardView_cardElevation
36318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     * @see #getCardElevation()
36418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     * @see #setMaxCardElevation(float)
36518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     */
366e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov    public void setCardElevation(float elevation) {
367ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        IMPL.setElevation(mCardViewDelegate, elevation);
36818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar    }
36918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar
37018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar    /**
37118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     * Returns the backward compatible elevation of the CardView.
37218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     *
37318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     * @return Elevation of the CardView
37418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     * @see #setCardElevation(float)
37518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     * @see #getMaxCardElevation()
37618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     */
37718ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar    public float getCardElevation() {
378ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        return IMPL.getElevation(mCardViewDelegate);
37918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar    }
38018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar
38118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar    /**
382e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * Updates the backward compatible maximum elevation of the CardView.
38318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     * <p>
384e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * Calling this method has no effect if device OS version is Lollipop or newer and
385bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar     * {@link #getUseCompatPadding()} is <code>false</code>.
38618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     *
387e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * @param maxElevation The backward compatible maximum elevation in pixels.
388e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * @attr ref android.support.v7.cardview.R.styleable#CardView_cardMaxElevation
38918ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     * @see #setCardElevation(float)
39018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     * @see #getMaxCardElevation()
39118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     */
392e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov    public void setMaxCardElevation(float maxElevation) {
393ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        IMPL.setMaxElevation(mCardViewDelegate, maxElevation);
39418ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar    }
39518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar
39618ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar    /**
397e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * Returns the backward compatible maximum elevation of the CardView.
39818ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     *
399e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * @return Maximum elevation of the CardView
40018ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     * @see #setMaxCardElevation(float)
40118ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     * @see #getCardElevation()
40218ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar     */
40318ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar    public float getMaxCardElevation() {
404ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        return IMPL.getMaxElevation(mCardViewDelegate);
40518ef68d444a1c059041bf5b683eb612ffed22ea9Yigit Boyar    }
406bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar
407c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar    /**
408c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     * Returns whether CardView should add extra padding to content to avoid overlaps with rounded
409e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * corners on pre-Lollipop platforms.
410c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     *
411e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * @return True if CardView prevents overlaps with rounded corners on platforms before Lollipop.
412c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     *         Default value is <code>true</code>.
413c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     */
414c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar    public boolean getPreventCornerOverlap() {
415c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar        return mPreventCornerOverlap;
416c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar    }
417c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar
418c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar    /**
419e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * On pre-Lollipop platforms, CardView does not clip the bounds of the Card for the rounded
420e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * corners. Instead, it adds padding to content so that it won't overlap with the rounded
421e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * corners. You can disable this behavior by setting this field to <code>false</code>.
422c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     * <p>
423e4548b3ac721f2b85f7b030d7043c94b24288670Kirill Grouchnikov     * Setting this value on Lollipop and above does not have any effect unless you have enabled
424c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     * compatibility padding.
425c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     *
426c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     * @param preventCornerOverlap Whether CardView should add extra padding to content to avoid
427c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     *                             overlaps with the CardView corners.
428c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     * @attr ref android.support.v7.cardview.R.styleable#CardView_cardPreventCornerOverlap
429c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     * @see #setUseCompatPadding(boolean)
430c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar     */
431c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar    public void setPreventCornerOverlap(boolean preventCornerOverlap) {
432ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        if (preventCornerOverlap != mPreventCornerOverlap) {
433ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            mPreventCornerOverlap = preventCornerOverlap;
434ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            IMPL.onPreventCornerOverlapChanged(mCardViewDelegate);
435c42ba8c000d1e6ce85e152dfc17089a0a69e739fYigit Boyar        }
436bdb07a1802c017efa64a5cfd8ab5a7ff4c4926b0Yigit Boyar    }
437ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes
438ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes    private final CardViewDelegate mCardViewDelegate = new CardViewDelegate() {
439ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        private Drawable mCardBackground;
440ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes
441ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        @Override
442ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        public void setCardBackground(Drawable drawable) {
443ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            mCardBackground = drawable;
444ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            setBackgroundDrawable(drawable);
445ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        }
446ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes
447ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        @Override
448ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        public boolean getUseCompatPadding() {
449ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            return CardView.this.getUseCompatPadding();
450ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        }
451ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes
452ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        @Override
453ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        public boolean getPreventCornerOverlap() {
454ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            return CardView.this.getPreventCornerOverlap();
455ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        }
456ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes
457ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        @Override
458ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        public void setShadowPadding(int left, int top, int right, int bottom) {
459ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            mShadowBounds.set(left, top, right, bottom);
460ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            CardView.super.setPadding(left + mContentPadding.left, top + mContentPadding.top,
461ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes                    right + mContentPadding.right, bottom + mContentPadding.bottom);
462ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        }
463ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes
464ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        @Override
465ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        public void setMinWidthHeightInternal(int width, int height) {
466ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            if (width > mUserSetMinWidth) {
467ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes                CardView.super.setMinimumWidth(width);
468ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            }
469ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            if (height > mUserSetMinHeight) {
470ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes                CardView.super.setMinimumHeight(height);
471ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            }
472ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        }
473ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes
474ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        @Override
475ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        public Drawable getCardBackground() {
476ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            return mCardBackground;
477ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        }
478ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes
479ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        @Override
480ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        public View getCardView() {
481ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes            return CardView.this;
482ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes        }
483ffbf42aa3acb41b82cc6c1226c63c3649bedfe49Chris Banes    };
484bc943f7fa746c149c5e4c3a4eed7febe494d5df5Yigit Boyar}
485