效果图

为了更方便的实现UI效果图里的圆角+阴影,就自定义了布局RoundShadowLayout

逻辑思路

  1. 设置布局的圆角,将子view超出圆角的区域裁剪掉
  2. 设置阴影,不改变子view的大小,将布局大小扩充到可以容纳阴影,并调整子view的位置

裁剪实现方案

  1. 使用canvas.clipXXX()方法裁剪画图区域(存在锯齿,不使用)
  2. 使用paint的Xfermode进行处理,获得需要效果(使用)
  3. 使用ViewOutLineProvider(需要21以上,不能单独设置某个圆角,不使用)

阴影实现方案

  1. 使用paint.setShadowLayer()方法

主要实现代码

//设置布局大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//super.onMeasure(widthMeasureSpec, heightMeasureSpec);// 测量子view的最大宽高int width = 0;int height = 0;for (int i=0;i<getChildCount();i++) {View child = getChildAt(i);//测量子View的宽高,measureChild最终调用child.measure(w,h)final ViewGroup.LayoutParams lp = child.getLayoutParams();final int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec-(int) (shadowRadius)*2, getPaddingLeft() + getPaddingRight(), lp.width);final int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec-(int) (shadowRadius)*2, getPaddingTop() + getPaddingBottom(), lp.height);child.measure(childWidthMeasureSpec, childHeightMeasureSpec);MarginLayoutParams mlp = (MarginLayoutParams) child.getLayoutParams();int childWidth = child.getMeasuredWidth() + mlp.leftMargin + mlp.rightMargin;int childHeight = child.getMeasuredHeight() + mlp.topMargin + mlp.bottomMargin;width = Math.max(width, childWidth);height = Math.max(height, childHeight);}//如果使用阴影,则宽高加上阴影setMeasuredDimension(width + getPaddingLeft() + getPaddingRight() + (int) (shadowRadius)*2,height + getPaddingTop() + getPaddingBottom() + (int) (shadowRadius)*2);
}
//添加阴影bitmap,最后将bitmap设置为布局的background
private Bitmap createShadowBitmap(int shadowWidth, int shadowHeight, float shadowRadius,float dx, float dy, int shadowColor) {Bitmap output = Bitmap.createBitmap(shadowWidth, shadowHeight, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(output);shadowRect.set(shadowRadius,shadowRadius,shadowWidth - shadowRadius,shadowHeight - shadowRadius);if (dy > 0) {shadowRect.top += dy;shadowRect.bottom -= dy;} else if (dy < 0) {shadowRect.top += Math.abs(dy);shadowRect.bottom -= Math.abs(dy);}if (dx > 0) {shadowRect.left += dx;shadowRect.right -= dx;} else if (dx < 0) {shadowRect.left += Math.abs(dx);shadowRect.right -= Math.abs(dx);}shadowPaint.setAntiAlias(true);shadowPaint.setStyle(Paint.Style.FILL);shadowPaint.setColor(shadowColor);if (!isInEditMode()) {shadowPaint.setShadowLayer(shadowRadius, dx, dy, shadowColor);}shadowPath.reset();shadowPath.addRoundRect(shadowRect, radiusArray, Path.Direction.CW);canvas.drawPath(shadowPath, shadowPaint);return output;
}
//裁剪圆角区域
private void clipRound(Canvas canvas) {roundPath.reset();roundPath.addRoundRect(roundRect, radiusArray, Path.Direction.CW);//画笔设置roundPaint.setColor(Color.WHITE);roundPaint.setAntiAlias(true);roundPaint.setStyle(Paint.Style.FILL);if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) {roundPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));canvas.drawPath(roundPath, roundPaint);} else {roundPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));final Path path = new Path();path.addRect(0, 0, getWidth(), getHeight(), Path.Direction.CW);path.op(roundPath, Path.Op.DIFFERENCE);canvas.drawPath(path, roundPaint);}
}

源代码https://github.com/wudengwei/RoundShadowLayout

参考 rclayout、shadow-layout

Android 自定义圆角+阴影布局相关推荐

  1. android imageview 锯齿,[置顶] android 自定义圆角ImageView以及锯齿的处理

    看到很多人开发过程中要使用圆角图片时,解决方法有: 1.重新绘制一张图片 2.通过布局来配置 3.通过重写View来实现 其中1,2在这里就不讲了,重点讲讲方法三的实现. 实现一:通过截取画布一个圆形 ...

  2. Android自定义圆角边框

    Android自定义圆角边框 一. 说明 本文主要讲如何自定义一个圆角的边框 二. 所用工具 Android Studio 三. 内容 1. 涉及到的内容 solid:设置背景色 stroke:设置边 ...

  3. Android 自定义圆角布局

    在android 开发中,图片或者button 有圆角的布局显得格外的美观些,所以今天就来 自定义圆角布局,只要把控件放入圆角布局中,然后设置属性就能实现圆角布局样式 接下来就来实现这样的功能 效果图 ...

  4. Android自定义menu菜单布局

    一:先写一个自定义的菜单布局 menu_gallery.xml: <?xml version="1.0" encoding="utf-8"?> &l ...

  5. android自定义圆角进度条,Android自定义进度条的圆角横向进度条实例详解

    1.本文将向你介绍自定义进度条的写法,比较简单,但还是有些知识点是需要注意的: invalidate()方法 RectF方法的应用 onMeasure方法的应用 2.原理 画3层圆角矩形,底层为黑色, ...

  6. Android自定义圆角圆形图片

    转载请注明出处:http://blog.csdn.net/binbinqq86/article/details/79463977 说起Android里面的自定义圆角圆形图片,已经算是老生常谈的话题了, ...

  7. android自定义dialog布局文件,Android自定义Dialog及其布局

    实际项目开发中默认的Dialog无法满足需求,需要自定义Dialog及其布局,并响应布局中控件的事件. 上效果图: 自定义Dialog,LogoutDialog: 要将自定义布局传入构造函数中,才能在 ...

  8. android 自定义推送布局_Notification的基本用法以及使用RemoteView实现自定义布局

    Notification的作用 Notification是一种全局效果的通知,在系统的通知栏中显示.既然作为通知,其基本作用有: 显示接收到短消息.即时信息等 显示客户端的推送(广告.优惠.新闻等) ...

  9. Android自定义圆角矩形图片ImageView

    //自定义的圆形的ImageView类的实现代码如下:package com.xc.xcskin.view;import android.content.Context; import android ...

最新文章

  1. ThinkPHP URL模式和URL重写
  2. boost::regex模块部分正则匹配相关的测试程序
  3. spring无法用三级缓存解决循环依赖的问题分析
  4. Hello Python程序演练
  5. call to member function bind_param() on boolean...........
  6. Java连接程序数据源
  7. [2010-8-22]
  8. python变量循环写入txt文件_Python中将变量按行写入txt文本中
  9. 基于排队论模型的收银台服务系统的分析及可视化设计
  10. linux 修改网卡 mac地址命令,Centos系统下查看和修改网卡Mac地址(附ifconfig命令格式)...
  11. 从消费互联网到产业互联网:平台思维始终是主导
  12. mysql 1033_mysql报错1033 Incorrect information in file: ''''xxx.frm''''问题的解决方法(图)...
  13. deepin系统维护(系统扩容)deepin live
  14. 计算机科学与工程学院团委,湖南科技大学计算机科学与工程学院
  15. 泛型+IO流+网络编程
  16. 正式发布!Matlab配色神器TheColor
  17. 在vscode中配置和使用sass
  18. 2014522420145238《信息安全系统设计基础》实验一 开发环境的熟悉
  19. markdown无法显示图片的问题
  20. 看优酷 Node 重构之路,Serverless SSR 未来可期

热门文章

  1. 面对CRS离岸账户政策收紧,浅谈外贸企业与个人SOHO应对措施
  2. 带着问题读 TiDB 源码:Power BI Desktop 以 MySQL 驱动连接 TiDB 报错
  3. 【宝塔】【Windows】【Blessing-Skin】【我的世界】用宝塔Windows搭建皮肤站
  4. 《惯性导航》第二版秦永元 知识点总结之一 《第一章 绪论》
  5. 【深度学习】语义分割-综述(卷积)
  6. python第四周迭代器生成器序列化面向过程递归
  7. 【推荐】比IPH5更爱疯的G5
  8. halcon第一讲:基本操作
  9. 【步态识别】GLN 算法学习《Gait Lateral Network: Learning Discriminative and Compact Representations for Gait R》
  10. PhotoZoom Pro中文免费版电脑版下载V.2020.6 无损放大图片