问题
When I use cardUseCompatPadding to show shadow in my card view, top padding is bigger than left one. How to make both padding equal, because my ribbon looking not beautiful, it's bigger on top? Thanks.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- Green triangles for badge -->
<FrameLayout
android:id="@+id/ribbon_parts"
android:layout_width="58dp"
android:layout_height="58dp"
android:background="@drawable/ic_ribbon_parts"
android:visibility="gone"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="@+id/item_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:background="@color/red"
android:clickable="true"
android:foreground="?attr/selectableItemBackground"
android:theme="@style/LightGrayHighlightTheme"
card_view:cardBackgroundColor="@color/white"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="2dp"
card_view:cardPreventCornerOverlap="true"
card_view:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="130dp"
android:animateLayoutChanges="true"
android:orientation="horizontal"
android:background="@color/blue"
android:weightSum="3"> </LinearLayout>
</FrameLayout>
<!-- badge -->
<FrameLayout
android:id="@+id/ribbon_main"
android:layout_width="58dp"
android:layout_height="58dp"
android:background="@drawable/ic_ribbon_main"
android:visibility="gone"/>
https://www.shutterstock.com/search/new+blue+corner+ribbon
回答1:
Taken from the documentation:
This may cause Cards to have different sizes between Lollipop and before Lollipop. If you need to align CardView with other Views, you may need api version specific dimension resources to account for the changes. As an alternative, you can set this flag to true and CardView will add the same padding values on platforms Lollipop and after.
Next, you can add the indentation you need by using the margin attribute
example.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#2861">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="@+id/item_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="1dp"
android:layout_marginEnd="2dp"
android:layout_marginStart="2dp"
android:layout_marginTop="1dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
card_view:cardBackgroundColor="@android:color/white"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="2dp"
card_view:cardPreventCornerOverlap="false"
card_view:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="130dp"
android:animateLayoutChanges="true"
android:orientation="horizontal"
android:weightSum="3">
<!-- Your code here -->
</LinearLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
<!-- badge -->
<FrameLayout
android:id="@+id/ribbon_main"
android:layout_width="58dp"
android:layout_height="58dp"
android:layout_gravity="end"
android:background="@drawable/corner_ribbon"
android:visibility="visible" />
</FrameLayout>
Now it looks great on different versions of the API.
API 19 example
API 26 example
comparison side by side
In your project, you can use these settings for both CardView and FrameLayout (ribbon) to achieve the desired result.
example_2.xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#2861">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="@+id/item_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="18dp"
android:layout_marginTop="17dp"
android:clickable="true"
android:focusable="true"
android:foreground="?attr/selectableItemBackground"
card_view:cardBackgroundColor="@android:color/white"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="2dp"
card_view:cardPreventCornerOverlap="false"
card_view:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="130dp"
android:animateLayoutChanges="true"
android:orientation="horizontal"
android:weightSum="3">
<!-- Your code here -->
</LinearLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
<!-- badge -->
<FrameLayout
android:id="@+id/ribbon_main"
android:layout_width="58dp"
android:layout_height="58dp"
android:layout_gravity="end"
android:layout_marginEnd="16dp"
android:layout_marginTop="16dp"
android:background="@drawable/corner_ribbon"
android:visibility="visible" />
</FrameLayout>
increased indentation
回答2:
You can't fix this. When cardUseCompatPadding
flag is set, these methods are used to calculate padding on all API levels:
final static float SHADOW_MULTIPLIER = 1.5f;
static float calculateVerticalPadding(float maxShadowSize, float cornerRadius, addPaddingForCorners) {
if (addPaddingForCorners) {
return (float) (maxShadowSize * SHADOW_MULTIPLIER + (1 - COS_45) * cornerRadius);
} else {
return maxShadowSize * SHADOW_MULTIPLIER;
}
}
static float calculateHorizontalPadding(float maxShadowSize, float cornerRadius, boolean addPaddingForCorners) {
if (addPaddingForCorners) {
return (float) (maxShadowSize + (1 - COS_45) * cornerRadius);
} else {
return maxShadowSize;
}
}
addPaddingForCorners
is true when you use card_view:cardPreventCornerOverlap="true"
.
Perhaps setting some layout_marginTop
on ribbon_main
and ribbon_parts
will give you the desired effect?
回答3:
This is working for me, may be it would work for you too:
float cardelevation = cardView.getMaxCardElevation();
float cardradius = cardView.getRadius();
double cardcos = Math.cos(Math.toRadians(45));
int horizontalPadding = (int) (cardelevation + (1 - cardcos ) * cardradius);
int verticalPadding = (int) (cardelevation * 1.5 + (1 - cardcos ) * cardradius);
Thank You.
来源:https://stackoverflow.com/questions/49150345/how-to-override-standart-padding-in-cardview-while-using-cardusecompatpadding