[英]Changing CardView shadow color
This question was asked on SO many times, but still I didn't find a good solution for this problem.这个问题被问了很多次,但我仍然没有找到解决这个问题的好方法。
Why do I need this to do?为什么我需要这样做? Well because project me and my team develops has iOS style.好吧,因为我和我的团队开发的项目具有 iOS 风格。
What did I try?我尝试了什么?
So is there a way to change shadow color of CardView with minimum edits of all layout files and with drawing shadow outside of the view like original CardView does?那么有没有一种方法可以像原始 CardView 一样,通过对所有布局文件进行最少的编辑并在视图外部绘制阴影来更改 CardView 的阴影颜色?
Consider this thread in twitter, where Nick Butcher talks about how to implement the feature:考虑推特上的这个帖子,尼克·布彻 (Nick Butcher) 谈到了如何实现该功能:
See outlineAmbientShadowColor
, outlineSpotShadowColor
, spotShadowAlpha
and ambientShadowAlpha
attributes for details.有关详细outlineAmbientShadowColor
,请参阅outlineAmbientShadowColor
、 outlineSpotShadowColor
、 spotShadowAlpha
和ambientShadowAlpha
属性。 Unfortunately, that's possible from API 28 onwards.不幸的是,从 API 28 开始这是可能的。
For lower APIs Nick has shared a gist .对于较低的 API,Nick 分享了一个要点。 Here's the result:结果如下:
Running on API 21在 API 21 上运行
This technique isn't directly connected to CardView
, it can be applied to any View
.这种技术不直接连接到CardView
,它可以应用于任何View
。
You Can Implement this without having a cardview, and can also have all the properties of cardview你可以在没有cardview的情况下实现这个,也可以拥有cardview的所有属性
You have to Do:你必须要做:
Copy the two classes复制两个类
Wrap your required view with the Custom View as in the example, you don't have to do much changes in your layout or anywhere else!如示例中所示,使用自定义视图包装所需的视图,您无需对布局或其他任何地方进行太多更改!
The below class will create a custom view, this will be wrapping your layout/View to be displayed in cardview with custom shadow color下面的类将创建一个自定义视图,这将包装您的布局/视图以使用自定义阴影颜色显示在 cardview 中
Create a class:创建一个类:
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.LinearLayout;
import com.qzion.nfscrew.R;
public class RoundLinerLayoutNormal extends LinearLayout {
public RoundLinerLayoutNormal(Context context) {
super(context);
initBackground();
}
public RoundLinerLayoutNormal(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
initBackground();
}
public RoundLinerLayoutNormal(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initBackground();
}
private void initBackground() {
setBackground(ViewUtils.generateBackgroundWithShadow(this,R.color.white,
R.dimen.radius_corner,R.color.colorPrimaryDark,R.dimen.elevation, Gravity.BOTTOM));
}
}
Also create the class for the Shadow Settings, ViewUtils.java还要为 Shadow Settings 创建类 ViewUtils.java
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.RoundRectShape;
import android.support.annotation.ColorRes;
import android.support.annotation.DimenRes;
import android.support.v4.content.ContextCompat;
import android.view.Gravity;
import android.view.View;
import static android.support.v4.view.ViewCompat.LAYER_TYPE_SOFTWARE;
public class ViewUtils {
public static Drawable generateBackgroundWithShadow(View view, @ColorRes int backgroundColor,
@DimenRes int cornerRadius,
@ColorRes int shadowColor,
@DimenRes int elevation,
int shadowGravity) {
float cornerRadiusValue = view.getContext().getResources().getDimension(cornerRadius);
int elevationValue = (int) view.getContext().getResources().getDimension(elevation);
int shadowColorValue = ContextCompat.getColor(view.getContext(),shadowColor);
int backgroundColorValue = ContextCompat.getColor(view.getContext(),backgroundColor);
float[] outerRadius = {cornerRadiusValue, cornerRadiusValue, cornerRadiusValue,
cornerRadiusValue, cornerRadiusValue, cornerRadiusValue, cornerRadiusValue,
cornerRadiusValue};
Paint backgroundPaint = new Paint();
backgroundPaint.setStyle(Paint.Style.FILL);
backgroundPaint.setShadowLayer(cornerRadiusValue, 0, 0, 0);
Rect shapeDrawablePadding = new Rect();
shapeDrawablePadding.left = elevationValue;
shapeDrawablePadding.right = elevationValue;
int DY;
switch (shadowGravity) {
case Gravity.CENTER:
shapeDrawablePadding.top = elevationValue;
shapeDrawablePadding.bottom = elevationValue;
DY = 0;
break;
case Gravity.TOP:
shapeDrawablePadding.top = elevationValue*2;
shapeDrawablePadding.bottom = elevationValue;
DY = -1*elevationValue/3;
break;
default:
case Gravity.BOTTOM:
shapeDrawablePadding.top = elevationValue;
shapeDrawablePadding.bottom = elevationValue*2;
DY = elevationValue/3;
break;
}
ShapeDrawable shapeDrawable = new ShapeDrawable();
shapeDrawable.setPadding(shapeDrawablePadding);
shapeDrawable.getPaint().setColor(backgroundColorValue);
shapeDrawable.getPaint().setShadowLayer(cornerRadiusValue/3, 0, DY, shadowColorValue);
view.setLayerType(LAYER_TYPE_SOFTWARE, shapeDrawable.getPaint());
shapeDrawable.setShape(new RoundRectShape(outerRadius, null, null));
LayerDrawable drawable = new LayerDrawable(new Drawable[]{shapeDrawable});
drawable.setLayerInset(0, elevationValue, elevationValue*2, elevationValue, elevationValue*2);
return drawable;
}
}
and finally your XML, where you have the views required to have shadow.最后是您的 XML,您可以在其中获得阴影所需的视图。
<com.qzion.nfscrew.utils.RoundLinerLayoutNormal
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This view will have shadow"/>
</com.qzion.nfscrew.utils.RoundLinerLayoutNormal>
Well I think of an easy solution without using a Java or Some Libraries.好吧,我想到了一个不使用 Java 或某些库的简单解决方案。 You should make a Drawable shape and put it in the drawable
folder and then adjust the gradient to be like a shadow.您应该制作一个 Drawable 形状并将其放在drawable
文件夹中,然后将渐变调整为像阴影一样。
For example, in my solution I have added two colors:例如,在我的解决方案中,我添加了两种颜色:
<color name="yellow_middle">#ffee58</color>
<color name="yellow_end">#7ae7de83</color>
Then I made a file and put it in drawable folder drawable\\card_view_shape.xml
然后我制作了一个文件并将其放入可绘制文件夹drawable\\card_view_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size
android:width="10dp"
android:height="10dp" />
<corners android:radius="6dp" />
<stroke
android:width="2dp"
android:color="@color/yellow_end" />
<gradient
android:angle="-90"
android:centerColor="@color/yellow_middle"
android:endColor="@color/yellow_end"
android:startColor="#fff" />
</shape>
Then from there you need to wrap a your view( that would have been inside CardView ) in a container like LinearLayout
then apply as the background to the container that you want to be seen like a cardview.然后从那里你需要将你的视图(本来在 CardView 里面)包装在一个像LinearLayout
这样的容器中,然后作为背景应用到你想要像 cardview 一样被看到的容器。 To solve it well add some padding (Thats your shadow) to the Container itself.为了很好地解决它,向容器本身添加一些填充(那是你的阴影)。 For instance check mine:例如检查我的:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.xenolion.ritetrends.MainActivity">
<LinearLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:background="@drawable/card_view_shape"
android:orientation="vertical"
android:paddingBottom="10dp"
android:paddingLeft="3dp"
android:paddingRight="3dp"
android:paddingTop="3dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
android:gravity="center"
android:text="I love StackOverflow"
android:textColor="#000"
android:textSize="18sp" />
</LinearLayout>
</FrameLayout>
Then the results looks like this:然后结果如下所示:
Adjusting the bottom padding it will look like this:调整底部填充它看起来像这样:
COMMENT评论
Since I am not of an artist but if you play with it you may make the whole thing look exactly like CardView
check some hints:因为我不是艺术家,但如果你玩它,你可能会让整个事情看起来和CardView
完全一样, CardView
检查一些提示:
CardView
.主 View 的背景对于带来现实也很重要,从那里重新设计形状,使其看起来更像CardView
逼真。display shadow >= 28 or >= P for above Sdk level 28显示阴影 >= 28 或 >= P 高于 Sdk 级别 28
use below code in your CardView在您的 CardView 中使用以下代码
with xml xml
android:outlineAmbientShadowColor="<yourCoolor>"
android:outlineSpotShadowColor="<yourCoolor>"
with java and kt file带有 java 和 kt 文件
mCardView.setOutlineAmbientShadowColor(ContextCompat.getColor(getContext(), R.color.color_new_yellow));
mCardView.setOutlineSpotShadowColor(ContextCompat.getColor(getContext(), R.color.color_new_yellow));
display like this像这样显示
Use Fake Shadow.使用假阴影。
Well, it is not possible to change the color of the shadow of cardview before API 28 but we can add a custom shadow behind a layout.好吧,在 API 28 之前无法更改 cardview 阴影的颜色,但我们可以在布局后面添加自定义阴影。 You need to use a drawable background ( shadow.xml
) in the parent layout which is looking like a shadow.您需要在看起来像阴影的父布局中使用可绘制背景( shadow.xml
)。
shadow.xml - shadow.xml -
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<solid android:color="#05FF46A9" />
<corners android:radius="15dp" />
</shape>
</item>
<item>
<shape>
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<solid android:color="#10FF46A9" />
<corners android:radius="15dp" />
</shape>
</item>
<item>
<shape>
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<solid android:color="#15FF46A9" />
<corners android:radius="15dp" />
</shape>
</item>
<item>
<shape>
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<solid android:color="#20FF46A9" />
<corners android:radius="15dp" />
</shape>
</item>
<item>
<shape>
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
<solid android:color="#25FF46A9" />
<corners android:radius="15dp" />
</shape>
</item>
</layer-list>
Now use the following code -现在使用以下代码 -
<FrameLayout
android:layout_width="match_parent"
android:background="@drawable/shadow"
android:layout_height="200dp">
<CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardCornerRadius="15dp"
app:cardElevation="0dp">
<!-- your code here -->
</CardView>
</FrameLayout>
You can replace FF46A9
in shadow.xml
to change the color of shadow.您可以替换FF46A9
中的shadow.xml
来更改阴影的颜色。 Also android:backgroundTint="@color/colorShadow"
works but you have to adjust colors alpha in shadow.xml. android:backgroundTint="@color/colorShadow"
可以工作,但您必须在 shadow.xml 中调整颜色 alpha。
Adjust the <corners android:radius="15dp"/>
as app:cardCornerRadius="15dp"
.将<corners android:radius="15dp"/>
为app:cardCornerRadius="15dp"
。
This trick is difficult to achieve in most cases , due Official Android Framework do not have any way to change the cardview shadow color.这个技巧在大多数情况下很难实现,因为官方 Android 框架没有任何方法来改变 cardview 阴影颜色。 In this case you refers to ilumination light on the cardview .在这种情况下,您指的是 cardview 上的照明灯。 This library is optimized for this this trick.该库针对此技巧进行了优化。
Library Link: https://github.com/meetsl/SCardView-master I hope can help you!库链接: https : //github.com/meetsl/SCardView-master希望能帮到你! Good Luck祝你好运
enter image description here I know I'm late but I want to share the solution as I searched hard for this issue and solved the issue The solution is, You have to use "ComplexView" to create your custom shadow,在这里输入图片描述我知道我来晚了,但我想分享解决方案,因为我努力搜索这个问题并解决了这个问题解决方案是,你必须使用“ComplexView”来创建你的自定义阴影,
dependency: implementation 'com.github.BluRe-CN:ComplexView:v1.1'
依赖: implementation 'com.github.BluRe-CN:ComplexView:v1.1'
XML: XML:
<com.blure.complexview.ComplexView
android:id="@+id/shadow_card_1"
android:layout_width="@dimen/_65sdp"
android:layout_height="@dimen/_65sdp"
android:layout_centerInParent="true"
app:radius="@dimen/_30sdp"
app:shadow="true"
app:shadowAlpha="250"
app:shadowSpread="2"/>
//this will create the circular shadow for my need you can reduce the radius //这将为我的需要创建圆形阴影你可以减少半径
Custom View自定义视图
val shadow = ComplexView(context)
val radii = floatArrayOf(100f, 100f, 100f, 100f, 100f, 100f, 100f, 100f)//customise according to your requirement
val opacity = 150//customise according to your requirement
shadow.shadow =Shadow(
2,
opacity,
"#96B9BB",
GradientDrawable.RECTANGLE,
radii,
Shadow.Position.CENTER
)
val param: RelativeLayout.LayoutParams =
RelativeLayout.LayoutParams(
context.resources.getDimension(R.dimen._160sdp).toInt(),
context.resources.getDimension(R.dimen._160sdp).toInt()
)
shadow.layoutParams = param
shadow.addView(yourCustomView)
thanks:)谢谢:)
Simple way to change card 's shadow color is to set android:outlineSpotShadowColor="@color/#CCCCCC"
inside your CardView更改卡片阴影颜色的简单方法是在android:outlineSpotShadowColor="@color/#CCCCCC"
设置android:outlineSpotShadowColor="@color/#CCCCCC"
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardElevation="15dp"
android:outlineAmbientShadowColor="@color/#CCCCCC"
android:outlineSpotShadowColor="@color/#CCCCCC" />
Already late for the answer.回答已经晚了。
Some trick can work perfectly for me一些技巧可以完美地为我工作
And XML file like和 XML 文件一样
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:id="@+id/cardview"
android:layout_width="@dimen/_150sdp"
android:layout_height="@dimen/_150sdp"
android:layout_marginLeft="@dimen/_10sdp"
android:layout_marginRight="@dimen/_10sdp"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="@dimen/_5sdp"
app:cardUseCompatPadding="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="@dimen/_50sdp"
android:orientation="vertical">
</LinearLayout>
<View
android:id="@+id/view_color"
android:layout_width="match_parent"
android:layout_height="@dimen/_2sdp"
android:layout_gravity="bottom"
android:background="@color/app_green" />
</androidx.cardview.widget.CardView>
</LinearLayout>
Enjoy coding享受编码
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.