Android 自定义圆角+阴影布局
效果图
为了更方便的实现UI效果图里的圆角+阴影,就自定义了布局RoundShadowLayout
逻辑思路
- 设置布局的圆角,将子view超出圆角的区域裁剪掉
- 设置阴影,不改变子view的大小,将布局大小扩充到可以容纳阴影,并调整子view的位置
裁剪实现方案
- 使用canvas.clipXXX()方法裁剪画图区域(存在锯齿,不使用)
- 使用paint的Xfermode进行处理,获得需要效果(使用)
- 使用ViewOutLineProvider(需要21以上,不能单独设置某个圆角,不使用)
阴影实现方案
使用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 自定义圆角+阴影布局相关推荐
- android imageview 锯齿,[置顶] android 自定义圆角ImageView以及锯齿的处理
看到很多人开发过程中要使用圆角图片时,解决方法有: 1.重新绘制一张图片 2.通过布局来配置 3.通过重写View来实现 其中1,2在这里就不讲了,重点讲讲方法三的实现. 实现一:通过截取画布一个圆形 ...
- Android自定义圆角边框
Android自定义圆角边框 一. 说明 本文主要讲如何自定义一个圆角的边框 二. 所用工具 Android Studio 三. 内容 1. 涉及到的内容 solid:设置背景色 stroke:设置边 ...
- Android 自定义圆角布局
在android 开发中,图片或者button 有圆角的布局显得格外的美观些,所以今天就来 自定义圆角布局,只要把控件放入圆角布局中,然后设置属性就能实现圆角布局样式 接下来就来实现这样的功能 效果图 ...
- Android自定义menu菜单布局
一:先写一个自定义的菜单布局 menu_gallery.xml: <?xml version="1.0" encoding="utf-8"?> &l ...
- android自定义圆角进度条,Android自定义进度条的圆角横向进度条实例详解
1.本文将向你介绍自定义进度条的写法,比较简单,但还是有些知识点是需要注意的: invalidate()方法 RectF方法的应用 onMeasure方法的应用 2.原理 画3层圆角矩形,底层为黑色, ...
- Android自定义圆角圆形图片
转载请注明出处:http://blog.csdn.net/binbinqq86/article/details/79463977 说起Android里面的自定义圆角圆形图片,已经算是老生常谈的话题了, ...
- android自定义dialog布局文件,Android自定义Dialog及其布局
实际项目开发中默认的Dialog无法满足需求,需要自定义Dialog及其布局,并响应布局中控件的事件. 上效果图: 自定义Dialog,LogoutDialog: 要将自定义布局传入构造函数中,才能在 ...
- android 自定义推送布局_Notification的基本用法以及使用RemoteView实现自定义布局
Notification的作用 Notification是一种全局效果的通知,在系统的通知栏中显示.既然作为通知,其基本作用有: 显示接收到短消息.即时信息等 显示客户端的推送(广告.优惠.新闻等) ...
- Android自定义圆角矩形图片ImageView
//自定义的圆形的ImageView类的实现代码如下:package com.xc.xcskin.view;import android.content.Context; import android ...
最新文章
- ThinkPHP URL模式和URL重写
- boost::regex模块部分正则匹配相关的测试程序
- spring无法用三级缓存解决循环依赖的问题分析
- Hello Python程序演练
- call to member function bind_param() on boolean...........
- Java连接程序数据源
- [2010-8-22]
- python变量循环写入txt文件_Python中将变量按行写入txt文本中
- 基于排队论模型的收银台服务系统的分析及可视化设计
- linux 修改网卡 mac地址命令,Centos系统下查看和修改网卡Mac地址(附ifconfig命令格式)...
- 从消费互联网到产业互联网:平台思维始终是主导
- mysql 1033_mysql报错1033 Incorrect information in file: ''''xxx.frm''''问题的解决方法(图)...
- deepin系统维护(系统扩容)deepin live
- 计算机科学与工程学院团委,湖南科技大学计算机科学与工程学院
- 泛型+IO流+网络编程
- 正式发布!Matlab配色神器TheColor
- 在vscode中配置和使用sass
- 2014522420145238《信息安全系统设计基础》实验一 开发环境的熟悉
- markdown无法显示图片的问题
- 看优酷 Node 重构之路,Serverless SSR 未来可期
热门文章
- 面对CRS离岸账户政策收紧,浅谈外贸企业与个人SOHO应对措施
- 带着问题读 TiDB 源码:Power BI Desktop 以 MySQL 驱动连接 TiDB 报错
- 【宝塔】【Windows】【Blessing-Skin】【我的世界】用宝塔Windows搭建皮肤站
- 《惯性导航》第二版秦永元 知识点总结之一 《第一章 绪论》
- 【深度学习】语义分割-综述(卷积)
- python第四周迭代器生成器序列化面向过程递归
- 【推荐】比IPH5更爱疯的G5
- halcon第一讲:基本操作
- 【步态识别】GLN 算法学习《Gait Lateral Network: Learning Discriminative and Compact Representations for Gait R》
- PhotoZoom Pro中文免费版电脑版下载V.2020.6 无损放大图片