以编程方式设置 CardView 海拔
Setting CardView elevation programmatically
我不知道这种方法是否最好,但我遇到了以下问题:
我希望 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 的高度之外,一切都工作正常(或者至少可以说是预期的)。我尝试手动设置海拔高度,但没有显示海拔高度。
EDIT______
我的 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 可绘制对象,右侧有一条红线。对于实现我的目标的另一种方法,您有什么建议吗?
你应该调用 setCardElevation
rather than setElevation
. The second one modifies the property elevation
,自 Lollipop(API 级别 21)以来所有 View
子类都有。
并且不使用 setBackgroundResource
:卡片背景是它的高度(这是因为卡片兼容Lollipop之前的所有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();
尝试使用
cardview.setMaxCardElevation();
但请注意:
Calling this method has no effect if device OS version is Lollipop or
newer and getUseCompatPadding() is false.
或尝试
cardview.setCardElevation();
或来自xml:
将 android:clipChildren="false"
添加到您的 cardview 的父级或向您的视图添加少量填充并设置 android:clipToPadding="false"
并使用
card_view:cardElevation="VALUE"
视图的 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()
,用于在视图周围重新绘制阴影。
我不知道这种方法是否最好,但我遇到了以下问题:
我希望 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 的高度之外,一切都工作正常(或者至少可以说是预期的)。我尝试手动设置海拔高度,但没有显示海拔高度。
EDIT______
我的 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 可绘制对象,右侧有一条红线。对于实现我的目标的另一种方法,您有什么建议吗?
你应该调用 setCardElevation
rather than setElevation
. The second one modifies the property elevation
,自 Lollipop(API 级别 21)以来所有 View
子类都有。
并且不使用 setBackgroundResource
:卡片背景是它的高度(这是因为卡片兼容Lollipop之前的所有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();
尝试使用
cardview.setMaxCardElevation();
但请注意:
Calling this method has no effect if device OS version is Lollipop or newer and getUseCompatPadding() is false.
或尝试
cardview.setCardElevation();
或来自xml:
将 android:clipChildren="false"
添加到您的 cardview 的父级或向您的视图添加少量填充并设置 android:clipToPadding="false"
并使用
card_view:cardElevation="VALUE"
视图的 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()
,用于在视图周围重新绘制阴影。