-
-
Save flore2003/943ef5e9fe316f903262 to your computer and use it in GitHub Desktop.
Utility class to calculate paddings and set margins on CardViews to correctly align them in a layout
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package de.twoid.widget.util; | |
/* | |
* Copyright 2015 Johannes Homeier, Florian Reifschneider | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
* | |
* | |
* Modified by Florian Reifschneider <[email protected]> to use the padding | |
* calculation from the support library. | |
*/ | |
import android.support.v7.widget.CardView; | |
import android.view.ViewGroup; | |
/** | |
* A utility-class providing methods to easily align a {@link android.support.v7.widget.CardView} in a layout by using margins | |
*/ | |
public class CardViewUtils { | |
// used to calculate content padding | |
final static double COS_45 = Math.cos(Math.toRadians(45)); | |
final static float SHADOW_MULTIPLIER = 1.5f; | |
/** | |
* Computes the compatPadding for the passed {@link CardView} | |
* | |
* @param cardView the CardView to generate the compatPadding from | |
* @return a array of integers with paddingLeft (position 0), paddingTop (position 1) ,paddingRight (position 2) and paddingBottom (position 3) | |
*/ | |
public static int[] getCompatPadding(CardView cardView) { | |
int[] compatPadding = new int[4]; | |
float elevation = cardView.getMaxCardElevation(); | |
float radius = cardView.getRadius(); | |
boolean addPaddingForCorners = cardView.getPreventCornerOverlap(); | |
compatPadding[0] = compatPadding[2] = (int) Math.ceil(calculateHorizontalPadding(elevation, radius, | |
addPaddingForCorners)); | |
compatPadding[1] = compatPadding[3] = (int) Math.ceil(calculateVerticalPadding(elevation, radius, | |
addPaddingForCorners)); | |
return compatPadding; | |
} | |
private static float calculateVerticalPadding(float maxShadowSize, float cornerRadius, | |
boolean addPaddingForCorners) { | |
if (addPaddingForCorners) { | |
return (float) (maxShadowSize * SHADOW_MULTIPLIER + (1 - COS_45) * cornerRadius); | |
} else { | |
return maxShadowSize * SHADOW_MULTIPLIER; | |
} | |
} | |
private static float calculateHorizontalPadding(float maxShadowSize, float cornerRadius, | |
boolean addPaddingForCorners) { | |
if (addPaddingForCorners) { | |
return (float) (maxShadowSize + (1 - COS_45) * cornerRadius); | |
} else { | |
return maxShadowSize; | |
} | |
} | |
/** | |
* Sets a compatMargin to the cardView so that the sum of compatMargin and compatPadding on either side sum up to the passed compatMargin for that side | |
* | |
* @param child the CardView to set the compatMargin to | |
* @param compatMarginLeft the compatMargin from the left of the cardviews content | |
* @param compatMarginTop the compatMargin from the top of the cardviews content | |
* @param compatMarginRight the compatMargin from the right of the cardviews content | |
* @param compatMarginBottom the compatMargin from the bottom of the cardviews content | |
* @param allowNegativePadding if true, the compatMargins can be negative (in case the computed compatPadding of the cardView is bigger than the compatMargin on the same side; otherwise, the compatMargin will be clamped to 0 | |
*/ | |
public static void setCompatMargin(CardView child, int compatMarginLeft, int compatMarginTop, int compatMarginRight, int compatMarginBottom, boolean allowNegativePadding) { | |
int[] compatPadding = getCompatPadding(child); | |
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) child.getLayoutParams(); | |
params.leftMargin = allowNegativePadding ? compatMarginLeft - compatPadding[0] : Math.max(0, compatMarginLeft - compatPadding[0]); | |
params.topMargin = allowNegativePadding ? compatMarginTop - compatPadding[1] : Math.max(0, compatMarginTop - compatPadding[1]); | |
params.rightMargin = allowNegativePadding ? compatMarginRight - compatPadding[2] : Math.max(0, compatMarginRight - compatPadding[2]); | |
params.bottomMargin = allowNegativePadding ? compatMarginBottom - compatPadding[3] : Math.max(0, compatMarginBottom - compatPadding[3]); | |
} | |
/** | |
* Sets a compatMargin to the cardView so that the sum of compatMargin and compatPadding on either side sum up to the passed compatMargin for that side; | |
* If the resulting margin for a side is negative, it will be set to 0. | |
* | |
* @param child the CardView to set the compatMargin to | |
* @param compatMarginLeft the compatMargin from the left of the cardviews content | |
* @param compatMarginTop the compatMargin from the top of the cardviews content | |
* @param compatMarginRight the compatMargin from the right of the cardviews content | |
* @param compatMarginBottom the compatMargin from the bottom of the cardviews content | |
*/ | |
public static void setCompatMargin(CardView child, int compatMarginLeft, int compatMarginTop, int compatMarginRight, int compatMarginBottom) { | |
setCompatMargin(child, compatMarginLeft, compatMarginTop, compatMarginRight, compatMarginBottom, false); | |
} | |
/** | |
* Sets a compatMargin to the cardView so that the sum of compatMargin and compatPadding on either side sum up to the passed compatMargin for that side; | |
* | |
* @param child the CardView to set the compatMargin to | |
* @param compatMarginLeftRight the compatMargin from the left and right of the cardviews content | |
* @param compatMarginTopBottom the compatMargin from the top and bottom of the cardviews content | |
* @param allowNegativePadding if true, the compatMargins can be negative (in case the computed compatPadding of the cardView is bigger than the compatMargin on the same side; otherwise, the compatMargin will be clamped to 0 | |
*/ | |
public static void setCompatMargin(CardView child, int compatMarginLeftRight, int compatMarginTopBottom, boolean allowNegativePadding) { | |
setCompatMargin(child, compatMarginLeftRight, compatMarginTopBottom, compatMarginLeftRight, compatMarginTopBottom, allowNegativePadding); | |
} | |
/** | |
* Sets a compatMargin to the cardView so that the sum of compatMargin and compatPadding on either side sum up to the passed compatMargin for that side; | |
* If the resulting margin for a side is negative, it will be set to 0. | |
* | |
* @param child the CardView to set the compatMargin to | |
* @param compatMarginLeftRight the compatMargin from the left and right of the cardviews content | |
* @param compatMarginTopBottom the compatMargin from the top and bottom of the cardviews content | |
*/ | |
public static void setCompatMargin(CardView child, int compatMarginLeftRight, int compatMarginTopBottom) { | |
setCompatMargin(child, compatMarginLeftRight, compatMarginTopBottom, compatMarginLeftRight, compatMarginTopBottom); | |
} | |
/** | |
* Sets a compatMargin to the cardView so that the sum of compatMargin and compatPadding on either side sum up to the passed compatMargin for that side; | |
* | |
* @param child the CardView to set the compatMargin to | |
* @param compatMargin the compatMargin from the left, top, right and bottom of the cardviews content | |
* @param allowNegativePadding if true, the compatMargins can be negative (in case the computed compatPadding of the cardView is bigger than the compatMargin on the same side; otherwise, the compatMargin will be clamped to 0 | |
*/ | |
public static void setCompatMargin(CardView child, int compatMargin, boolean allowNegativePadding) { | |
setCompatMargin(child, compatMargin, compatMargin, compatMargin, compatMargin, allowNegativePadding); | |
} | |
/** | |
* Sets a compatMargin to the cardView so that the sum of compatMargin and compatPadding on either side sum up to the passed compatMargin for that side; | |
* If the resulting margin for a side is negative, it will be set to 0. | |
* | |
* @param child the CardView to set the compatMargin to | |
* @param compatMargin the compatMargin from the left, top, right and bottom of the cardviews content | |
*/ | |
public static void setCompatMargin(CardView child, int compatMargin) { | |
setCompatMargin(child, compatMargin, compatMargin, compatMargin, compatMargin); | |
} | |
/** | |
* Computes the dimension of the CardViews content | |
* | |
* @param cardView | |
* @return a array of integers with width (position 0) and height (position 1) of the CardViews content | |
*/ | |
public static int[] getContentDimension(CardView cardView) { | |
int[] compatPadding = getCompatPadding(cardView); | |
return new int[]{ | |
cardView.getWidth() - compatPadding[0] - compatPadding[2] | |
, cardView.getHeight() - compatPadding[1] - compatPadding[3] | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I wonder if the additional padding from preventCornerOverlap is correct.. i thought it was used to inset the content in the card from the borders of the card, not the borders of the view.
Besides that a welcomed refinement =)