我们在EasyConstraintLayout中初始化paint,并且关闭硬件加速,然后在drawChild中实现阴影逻辑,最终代码如下。

public class EasyConstraintLayout extends ConstraintLayout {
private Paint shadowPaint;
private Paint clipPaint;

public EasyConstraintLayout(Context context, AttributeSet attrs) {
super(context, attrs);
shadowPaint = new Paint();
shadowPaint.setAntiAlias(true);
shadowPaint.setDither(true);
shadowPaint.setFilterBitmap(true);
shadowPaint.setStyle(Paint.Style.FILL);

clipPaint = new Paint();
clipPaint.setAntiAlias(true);
clipPaint.setDither(true);
clipPaint.setFilterBitmap(true);
clipPaint.setStyle(Paint.Style.FILL);
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}

@Override
public ConstraintLayout.LayoutParams generateLayoutParams(AttributeSet attrs) {
return new LayoutParams(getContext(), attrs);
}

@Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
for (int i = 0, size = getChildCount(); i < size; i++) {
View v = getChildAt(i);
ViewGroup.LayoutParams lp = v.getLayoutParams();
if (lp instanceof EasyLayoutParams) {
EasyLayoutParams elp = (EasyLayoutParams) lp;
elp.getData().initPaths(v);
}
}
}

@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
ViewGroup.LayoutParams lp = child.getLayoutParams();
boolean ret = false;
if (lp instanceof EasyLayoutParams) {
EasyLayoutParams elp = (EasyLayoutParams) lp;
LayoutParamsData data = elp.getData();
if (isInEditMode()) {//预览模式采用裁剪
canvas.save();
canvas.clipPath(data.widgetPath);
ret = super.drawChild(canvas, child, drawingTime);
canvas.restore();
return ret;
}
if (!data.hasShadow && !data.needClip)
return super.drawChild(canvas, child, drawingTime);
//为解决锯齿问题,正式环境采用xfermode
if (data.hasShadow) {
int count = canvas.saveLayer(null, null, Canvas.ALL_SAVE_FLAG);
shadowPaint.setShadowLayer(data.shadowEvaluation, data.shadowDx, data.shadowDy, data.shadowColor);
shadowPaint.setColor(data.shadowColor);
canvas.drawPath(data.widgetPath, shadowPaint);
shadowPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
shadowPaint.setColor(Color.WHITE);
canvas.drawPath(data.widgetPath, shadowPaint);
shadowPaint.setXfermode(null);
canvas.restoreToCount(count);

}
if (data.needClip) {
int count = canvas.saveLayer(child.getLeft(), child.getTop(), child.getRight(), child.getBottom(), null, Canvas.ALL_SAVE_FLAG);
ret = super.drawChild(canvas, child, drawingTime);
clipPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
clipPaint.setColor(Color.WHITE);
canvas.drawPath(data.clipPath, clipPaint);
clipPaint.setXfermode(null);
canvas.restoreToCount(count);
}
}
return ret;
}

static class LayoutParams extends ConstraintLayout.LayoutParams implements EasyLayoutParams {

private LayoutParamsData data;

public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
data = new LayoutParamsData(c, attrs);
}

@Override
public LayoutParamsData getData() {
return data;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
使用方法
<?xml version="1.0" encoding="utf-8"?>
<io.github.iamyours.easylayout.EasyConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<View
android:id="@+id/v_back"
android:layout_width="match_parent"
android:layout_height="150dp"
android:layout_margin="10dp"
android:background="#fff"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_radius="4dp"
app:layout_shadowColor="#3ccc"
app:layout_shadowEvaluation="15dp" />

<ImageView
android:id="@+id/iv_head"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="10dp"
android:background="#eee"
app:layout_constraintBottom_toBottomOf="@id/v_back"
app:layout_constraintLeft_toLeftOf="@id/v_back"
app:layout_constraintTop_toTopOf="@id/v_back"
app:layout_radius="40dp"
app:layout_shadowColor="#5f00"
app:layout_shadowEvaluation="8dp" />

<View
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginTop="30dp"
android:background="#ccc"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/v_back"
app:layout_radius="30dp"
app:layout_shadowColor="#8f0f"
app:layout_shadowDx="4dp"
app:layout_shadowDy="4dp"
app:layout_shadowEvaluation="10dp" />
</io.github.iamyours.easylayout.EasyConstraintLayout>
---------------------

drawChild中画阴影,裁剪出圆角的更多相关文章

  1. python—networkx:在一张图中画出多个子图

    通过plt.subplot能够在一张图中画出多个子图 #coding: utf-8 #!/usr/bin/env python """ Draw a graph with ...

  2. iOS高效裁剪图片圆角算法

    项目有个需求:裁剪图片,针对头像,下面是要求: 大家可以看到这张图片的圆角已经去除,下面说说我在项目利用了两种方式实现此裁剪以及查看技术文档发现更高效裁剪方式,下面一一讲解:看下来大约需要15-20分 ...

  3. 在ps中画两个同心圆并且把两个同心圆进行任意角度切割

    在工作中遇到要在ps中画如图两个同心圆,并且进行6等分.查找资料加自己摸索,可以通过以下方式实现: 1.新建一画布.并用通过标尺画出两条水平和垂直参考线,选择椭圆工具,并在选项设置中选择圆和从中心两个 ...

  4. Android Demo---如何敲出圆角的Button+圆角头像

    经常玩儿App的小伙伴都知道,APP上面有很多按钮都是圆角的,圆形给人感觉饱满,富有张力,不知道设计圆角按钮的小伙伴是不是和小编有着相同的想法`(*∩_∩*)′,听小编公司开发IOS的小伙伴说,他们里 ...

  5. css边框样式、边框配色、边框阴影、边框圆角、图片边框

     边框样式 点线式边框 破折线式边框 直线式边框 双线式边框 槽线式边框 脊线式边框 内嵌效果的边框 突起效果的边框 <div style="width: 300px; height: ...

  6. 如何在CorelDRAW中创建对象阴影

    阴影工具可以为对象创建光线映射的阴影效果,使对象产生较强的立体感.可以为大多数对象或群组对象添加阴影,其中包括美术字.段落文本和位图.创建对象阴影可以增加视觉层次,使图形更加逼真. CorelDRAW ...

  7. 用字体在网页中画Icon图标

    第一步,下载.IcoMoon网站选择字体图标并下载,解压后将fonts文件夹放在工程目录下.fonts文件夹内有四种格式的字体文件: 注:由于浏览器对每种字体的支持程度不一致,要想在所有浏览器中都显示 ...

  8. bootstrap中popover.js(弹出框)使用总结+案例

    bootstrap中popover.js(弹出框)使用总结+案例 *转载请注明出处: 作者:willingtolove: http://www.cnblogs.com/willingtolove/p/ ...

  9. 字体在网页中画ICON图标

    用字体在网页中画ICON图标有三种小技巧: 1.用CSS Sprite在网页中画小图标 实现方法: 首先将小图片整合到一张大的图片上 然后根据具体图标在大图上的位置,给背景定位.background- ...

随机推荐

  1. linux优化

    优化linux启动项 1. 使用ntsysv工具讲不需要的服务关闭 2. 默认启动服务可以只保留必要的服务 3. free -m 以m为单位 4. 删除不必要的用户: 5. cp /etc/passw ...

  2. 应用安全 - SuiteCRM - 漏洞汇总

    CVE-2019-12598.CVE-2019-12601 SuiteCRM SQL注入与远程代码执行漏洞 SalesAgility SuiteCRM .x版本..x版本和7..5之前的7..x版本中 ...

  3. Java设计模式——单例模式(static修饰)

    1.类的构造器私有化 2.本类内部创建对象(用本类内部public static静态方法返回该静态对象) 3.创建静态变量指向该类. 饿汉式和懒汉式的差异: 1.创建对象的时机不同!(饿汉模式在使用静 ...

  4. HDU 6070题解(二分+线段树)

    题面 传送门 此题的题意不是很清晰,要注意的一点是在区间[L,R]中,默认题目编号最后一次出现的时候是AC的 比如1 2 1 2 3 ,在区间[1,4]中,第3次提交时AC第1题,第4次提交时AC第2 ...

  5. 比Redux更容易上手的状态管理库

    前言 当项目越发复杂时,我们发现仅仅是提升状态已经无法适应如此复杂的状态管理了,程序状态变得比较难同步,操作,到处是回调,发布,订阅,这意味着我们需要更好的状态管理方式,于是就引入了状态管理库,如Re ...

  6. 面向切面编程 AOP 和装饰器??

    1.AOP概念:面向切面编程,指扩展功能不修改源代码,将功能代码从业务逻辑代码中分离出来. 主要功能:日志记录,性能统计,安全控制,事务处理,异常处理等等. 主要意图:将日志记录,性能统计,安全控制, ...

  7. Oracle 11g+Windows10 x64安装、配置过程记录

    备注:本想在自己电脑上安装个oracle练习用,但是害怕安装过程中出现问题,而oracle的卸载又是出了名的麻烦,所以用虚拟机搭建了一个跟本机一样的系统,同时记录下安装的每一步. 环境:windows ...

  8. Maven中添加Jetty服务器配置

    <project> <!--其它配置--> <build> <plugins> <plugin> <groupId>org.mo ...

  9. CentOS7修改为国内yum源

    备份源yum源 如果是国内下载的CentOS很可能国内YUM源已经设置好了. 备份/etc/yum.repos.d/下的*.repo文件. 在CentOS中配置使用网易和阿里的开源镜像 wget ht ...

  10. windows 2003 系统管理员debug