【问题标题】:Setting CardView elevation programmatically以编程方式设置 CardView 高程
【发布时间】:2017-07-12 18:16:31
【问题描述】:

我不知道这种方法是否最好,但我有以下问题:

我希望 RecyclerView 中的列表项(CardView)在其按钮被单击时被动画化,以便此按钮、该项中的其他一些视图以及 CardView 的背景发生变化。

我正在从自定义 RecyclerView.ItemAnimator 捕获 animateChange: (到目前为止,动画只是通过 animateLayoutChanges 在 xml 中定义的淡入淡出)

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;
}

如您所见,我在 animateChange 中手动设置背景。除了 CardView 的高度之外,一切正常(或者至少可以说是预期的)。我尝试手动设置高程,但没有显示高程。

编辑______

我的 CardView 里面有一个 ImageView 和一个按钮。按下按钮时,按钮本身和图片应该会淡出,并且cardView右侧应该有一条红线。我试图通过将背景(使用 setBackgroundResource)设置为此:

<?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>

这只是一个 xml drawable,右边有一条红线。对于实现我的目标的另一种方法,您有什么建议吗?

【问题讨论】:

  • I tried to set the elevation by hand, but there is no elevation shown 什么意思?
  • viewHolder.containerCardView.setElevation(20f); cardView 之前有一个高度,但在我设置新背景之后没有。所以我尝试用这行代码重新设置。
  • 为什么不直接在 XML 中设置呢?
  • CardView 在 XML 中有一个高程,但在设置背景后没有。
  • @Vancore 这正是你没有看到任何阴影的原因。

标签: android android-recyclerview elevation cardview


【解决方案1】:

您应该调用setCardElevation 而不是setElevation。第二个修改属性elevation,所有View 子类自Lollipop(API 级别21)以来都具有该属性。

并且不要使用 setBackgroundResource:卡片背景是它的海拔(这是因为卡片兼容棒棒糖之前的所有Android版本,没有elevation属性) .使用setCardBackgroundColor 设置背景颜色(或在您的xml 中设置app:cardBackgroundColor)。

如果您需要背景图片而不是颜色,请按照this answer 的建议在您的卡片内放置一个ImageView

做你想做的事,但不要在CardView 上调用任何setBackground... 方法,否则你将失去卡片阴影(它的提升效果)。

其次,使用以下代码为您的海拔设置动画:

ObjectAnimator animator = ObjectAnimator.ofFloat(cardView, "cardElevation", start, end);
// if needed set duration, interpolator, or what you want on the animator
animator.start();

【讨论】:

  • 您的卡片是否包含在另一个布局中?由于容器布局的clipChildrenclipToPadding 属性(默认为true),高程阴影可能根本不可见。
  • 我更新了答案。您的代码存在与错误使用 View 的方法有关的问题。
  • 我的 cardView 确实在 RelativeLayout 中。我删除了父RelativeLayout,因为我的cardView是recyclerView的一个行项,但仍然没有变化。问题是我不能简单地使用背景颜色,因为我想要特定的背景(右侧只有一条红线)
  • CardViewFrameLayout 的扩展:所以将ImageView 作为卡片的第一个儿子,并将您的背景作为此ImageView 的src(最终与scaleType )。 stackoverflow.com/a/33920684/1507512
  • 我更新了答案来解释当卡片视图被点击时如何正确地为立面设置动画
【解决方案2】:

尝试使用

cardview.setMaxCardElevation();

但请注意:

如果设备操作系统版本是 Lollipop 或 较新且 getUseCompatPadding() 为 false。

或者试试

cardview.setCardElevation();

Source

或来自 xml:

android:clipChildren="false" 添加到您的cardview 的父级或向您的视图添加少量填充并设置android:clipToPadding="false"

并使用

card_view:cardElevation="VALUE"

【讨论】:

  • clipTopadding 和 clipChildren 似乎对此没有影响。我认为问题出在其他地方。
  • @Vancore 不幸的是我没有想法!
【解决方案3】:

View 的Outline 是“驱动其阴影形状”的东西。当更改背景隐式更改视图的轮廓时,您必须通过调用 View.invalidateOutline() 显式地使轮廓无效,以便在视图周围重绘阴影。

【讨论】:

  • 欢迎来到 SO!请尝试解释一下您的答案。只需几句话和一些链接的答案应添加为 cmets 而不是答案。
猜你喜欢
  • 1970-01-01
  • 2019-10-28
  • 2018-11-14
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-14
相关资源
最近更新 更多