Skip to content

Instantly share code, notes, and snippets.

@flore2003
Forked from homj/CardViewUtils.java
Last active January 21, 2016 01:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flore2003/943ef5e9fe316f903262 to your computer and use it in GitHub Desktop.
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
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 <flore2003@googlemail.com> 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]
};
}
}
@homj
Copy link

homj commented Jan 28, 2015

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 =)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment