Setting CardView elevation programmatically

时光毁灭记忆、已成空白 提交于 2020-07-18 07:52:45

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!