问题
I do not know if this approach is the best, but I have the following problem:
I want a list item (a CardView) in a RecyclerView to be animated when it's button was clicked, so that this button, some other views inside this item and the background of the CardView changes.
I am catching the animateChange from a custom RecyclerView.ItemAnimator: (until now the animation is just a fade defined in the xml via animateLayoutChanges)
public boolean animateChange(@NonNull RecyclerView.ViewHolder oldHolder, @NonNull RecyclerView.ViewHolder newHolder, @NonNull ItemHolderInfo preLayoutInfo, @NonNull ItemHolderInfo postLayoutInfo) {
Log.d("Animation", "Test");
final MyAdapter.MyViewHolder viewHolder = (MyAdapter.MyViewHolder) newHolder;
viewHolder.mButtons.setVisibility(View.GONE);
viewHolder.mHints.setVisibility(View.GONE);
viewHolder.mImageView.setVisibility(View.GONE);
ViewGroup.LayoutParams layoutParams = viewHolder.containerCardView.getLayoutParams();
layoutParams.height = 192;
viewHolder.containerCardView.setLayoutParams(layoutParams);
viewHolder.containerCardView.setBackgroundResource(R.drawable.some_background);
viewHolder.containerCardView.setElevation(20f);
return true;
}
As you can see, I am setting the background manually in the animateChange. Everything works fine (or lets say at least as expected) except for the elevation of the CardView. I tried to set the elevation by hand, but there is no elevation shown.
EDIT______
My CardView has an ImageView and a button inside it. When pressing the button, the button itself and the picture should fade out and there shall be a red line on the right side of the cardView. I tried to achieve that by setting the background (with setBackgroundResource) to this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="180"
android:centerColor="@android:color/transparent"
android:centerX="0.1"
android:startColor="@android:color/holo_red_dark"/>
<corners
android:bottomLeftRadius="2dip"
android:bottomRightRadius="2dip"
android:topLeftRadius="2dip"
android:topRightRadius="2dip"/>
</shape>
</item>
<item android:right="4dp">
<shape android:shape="rectangle">
<solid android:color="@android:color/white" />
</shape>
</item>
</layer-list>
Which is just an xml drawable with a red line on the right. Do you have any suggestions for another way to approach my goal?
回答1:
You should call setCardElevation rather than setElevation
. The second one modifies the property elevation, which all View
subclasses have since Lollipop (API level 21).
And DON'T USE setBackgroundResource
: the card background is its elevation (this because the card is compatible with all Android versions before Lollipop, which don't have the elevation
property). Use setCardBackgroundColor
to set a background color (or app:cardBackgroundColor
in your xml).
If you need a background image, rather than a color, place an ImageView
inside of your card as this answer suggests.
Do what you want, but DON'T call any setBackground...
method on the CardView
, or you will lose the card shadow (its elevation effect).
Secondly, to animate your elevation use the following code:
ObjectAnimator animator = ObjectAnimator.ofFloat(cardView, "cardElevation", start, end);
// if needed set duration, interpolator, or what you want on the animator
animator.start();
回答2:
The View's Outline is what "drives the shape of its shadows". When changing the background implicitly changes the view's outline, you must explicitly invalidate the outline by calling View.invalidateOutline(), for the shadows to be redrawn around the view.
回答3:
try to use
cardview.setMaxCardElevation();
but note that:
Calling this method has no effect if device OS version is Lollipop or newer and getUseCompatPadding() is false.
Or try
cardview.setCardElevation();
Source
Or from xml:
Add android:clipChildren="false"
to the parent of your cardview or add a small amount of padding to your View and set android:clipToPadding="false"
and use
card_view:cardElevation="VALUE"
来源:https://stackoverflow.com/questions/42395879/setting-cardview-elevation-programmatically