https://cloud.tencent.com/developer/article/1854434 https://blog.csdn.net/zhyazaq/article/details/86513528?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-4.base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-4.base https://www.jianshu.com/p/9b5d111aa306 https://blog.csdn.net/fengyoujie/article/details/6531224 https://blog.csdn.net/chenhuakang/article/details/91984083
android shape实现阴影或模糊边效果
原文地址:https://www.cnblogs.com/linghu-java/p/10837421.html
android实现阴影的方式有很多,
1. Android 在 API21(5.0)添加了 elevation,可以很方便的在 View 上实现阴影。但是这个只在 >= API21 的手机上可以看到阴影效果,低于这个版本的就没有阴影效果。
2. CardView 也可以实现阴影效果,项目中一般都是使用这种方式实现卡片式的效果并带有阴影。使用 CardView 确实很不错,但是它在使用的时候也是需要有注意的地方:
(1) CardView 实现阴影效果的布局,在 >= API 21 的版本上和 < 21 的版本上,如果不在代码上做好控制,他们的显示差异还是很大的。(2) CardView 在 >= API21 的版本上实现阴影效果也是通过 elevation 来实现的,最终的渲染是调用 native 方法进行的。在使用过程中发现在不同位置的 View 阴影的方向是不一样的。不知道你们发现没,它模拟的场景就是 光源的位置在屏幕中心的正上方,然后 View 的位置由光源的位置决定。阴影方向不一致。
3. 通过 .9 图来制作阴影,这里通过一个很好的工具来制作哈:http://inloop.github.io/shadow4android/,这种方式制作小的背景阴影很模糊,效果上比不过 shape。
4. 用 SCardView 来实现阴影,使用方式和 CardView一样,但是它是使用一套代码,显示不会有差异,而且可以通过设置光源的位置来控制阴影的方向以及阴影的颜色。
compile 'io.github.meetsl:SCardView:1.0'
5. 通过shape来实现,具体是通过layer-list 多层叠放的方式实现的。
-
-
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
-
<!-- 边 -->
-
<item>
-
<shape android:shape="rectangle">
-
<padding
-
android:bottom="2dp"
-
android:left="2dp"
-
android:right="2dp"
-
android:top="2dp" />
-
<solid android:color="#00CCCCCC" />
-
<corners android:radius="8dp" />
-
</shape>
-
</item>
-
<item>
-
<shape android:shape="rectangle">
-
<padding
-
android:bottom="2dp"
-
android:left="2dp"
-
android:right="2dp"
-
android:top="2dp" />
-
<solid android:color="#10CCCCCC" />
-
<corners android:radius="8dp" />
-
</shape>
-
</item>
-
<item>
-
<shape android:shape="rectangle">
-
<padding
-
android:bottom="2dp"
-
android:left="2dp"
-
android:right="2dp"
-
android:top="2dp" />
-
<solid android:color="#20CCCCCC" />
-
<corners android:radius="8dp" />
-
</shape>
-
</item>
-
<item>
-
<shape android:shape="rectangle">
-
<padding
-
android:bottom="2dp"
-
android:left="2dp"
-
android:right="2dp"
-
android:top="2dp" />
-
<solid android:color="#30CCCCCC" />
-
<corners android:radius="8dp" />
-
</shape>
-
</item>
-
<item>
-
<shape android:shape="rectangle">
-
<padding
-
android:bottom="2dp"
-
android:left="2dp"
-
android:right="2dp"
-
android:top="2dp" />
-
<solid android:color="#50CCCCCC" />
-
<corners android:radius="8dp" />
-
</shape>
-
</item>
-
-
<!-- 中心背景 -->
-
<item>
-
<shape android:shape="rectangle"
-
android:useLevel="false">
-
<!-- 实心 -->
-
<solid android:color="#ffffff" />
-
<corners android:radius="10dp" />
-
<padding android:left="10dp"
-
android:right="10dp"
-
android:top="10dp"
-
android:bottom="10dp"/>
-
</shape>
-
</item>
-
</layer-list>
使用
1 android:background="@drawable/layer_white_bg"
各种方式的差异
方式 | 是否有显示差异 | 是否可以控制阴影方向 | 是否可以设置阴影颜色 | 阴影是否占位 | 是否模糊 | 绘制效率 | 其他 |
elevation | 无 | 不可控制 | 不可设置 | 不占位 | 不 | 高,通过 native 绘制 | 只在 API 21 生效 |
CardView | 有 | 不可控制 | 不可设置 | 不占位 | 不 | Api 21 上效率高,通过native 绘制 | |
shape | 无 | 可控 | 可设置 | 占位 | 不 | 一般 | |
.9 图 | 无 | 可控,生效一次,更改需重新生成 | 可设置,更改需重新生成 | 占位 | 模糊 | 慢(加载图片显示) | |
SCardView | 无 | 可控 | 可设置 | 不占位 | 不 | 一般 |
https://blog.csdn.net/chenhuakang/article/details/91984083
###################################################################################################################################################
Android 图片实现阴影效果的若干种方法
第一种 使用 layer-list
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!--底层的左边距离上层左边3dp, 底层的顶部,距离上层的顶部6dp,如果不做这个控制,底层和上层的左侧和上侧会重合在一起-->
<item android:left="3dp"
android:top="6dp">
<shape>
<solid android:color="#b4b5b6"/>
</shape>
</item>
<!--上层的右边距离底层的右边3dp, 上层的底部距离底层的底部6dp-->
<item android:bottom="6dp"
android:right="3dp">
<shape>
<solid android:color="#fff"/>
</shape>
</item>
</layer-list>
第二种 使用 shadow属性
shadowDX、shadowDy、shadowRadius,分别指的是阴影的横、纵坐标偏移,以及阴影的半径,
如果是TextView可以直接在布局中设置:
<TextView
android:id="@+id/test_shadow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="60sp"
android:textColor="#cc000000"
android:text="Test Shadow"
android:layout_gravity="center"
android:shadowColor="#aa22ff22"
android:shadowRadius="10"
android:shadowDx="0"
android:shadowDy="0"
/>
第三种 使用android:elevation属性
<TextView
android:id="@+id/btn_test_performance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="5dp"
android:text="@string/hello"
android:background="@drawable/shape_round_white"
android:padding="20dp"
android:layout_marginTop="10dp"
android:layout_gravity="center"/>
这种方式有个局限性, 那就是api25以上才能显示出来
第四种 使用第三方控件
/**
* ShadowLayout.java
* <p>
* Created by lijiankun on 17/8/11.
*/
public class ShadowLayout extends RelativeLayout {
public static final int ALL = 0x1111;
public static final int LEFT = 0x0001;
public static final int TOP = 0x0010;
public static final int RIGHT = 0x0100;
public static final int BOTTOM = 0x1000;
private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private RectF mRectF = new RectF();
/**
* 阴影的颜色
*/
private int mShadowColor = Color.TRANSPARENT;
/**
* 阴影的大小范围
*/
private float mShadowRadius = 0;
/**
* 阴影 x 轴的偏移量
*/
private float mShadowDx = 0;
/**
* 阴影 y 轴的偏移量
*/
private float mShadowDy = 0;
/**
* 阴影显示的边界
*/
private int mShadowSide = ALL;
public ShadowLayout(Context context) {
this(context, null);
}
public ShadowLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ShadowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
/**
* 获取绘制阴影的位置,并为 ShadowLayout 设置 Padding 以为显示阴影留出空间
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
float effect = mShadowRadius + dip2px(5);
float rectLeft = 0;
float rectTop = 0;
float rectRight = this.getWidth();
float rectBottom = this.getHeight();
int paddingLeft = 0;
int paddingTop = 0;
int paddingRight = 0;
int paddingBottom = 0;
if (((mShadowSide & LEFT) == LEFT)) {
rectLeft = effect;
paddingLeft = (int) effect;
}
if (((mShadowSide & TOP) == TOP)) {
rectTop = effect;
paddingTop = (int) effect;
}
if (((mShadowSide & RIGHT) == RIGHT)) {
rectRight = this.getWidth() - effect;
paddingRight = (int) effect;
}
if (((mShadowSide & BOTTOM) == BOTTOM))