Android之控件阴影模糊效果死磕Paint.setShadowLayer()
16lz
2021-01-25
IOS界面那么好看,不服气呀,android应该也是支持模糊阴影的, Paint.setShadowLayer官方文档
上一篇可以实现阴影,但是没有模糊效果,本文加上模糊效果
本文只是一个测试代码,属于抛砖引玉的,读者可以通过修改完善源码实现更好的效果
Paint.setShadowLayer是支持设置阴影的,不过有几个坑
- 需要关闭硬件加速,否则没有效果
- 阴影的颜色是需要带透明度的,否则没有效果
思路
- 比如你有一个 200dp*100dp的矩形空间需要显示边界阴影,先通过计算布局大小,给这个区域设置padding, 这个padding的目的是给阴影留下位置,阴影区域的大小是原空间的大小,给出的代码是一个ViewGroup,可以直接使用
- 效果还是可以的 (测试代码,只是右侧阴影和底部多一点阴影)
- 使用方法, 里面可以放任意的布局,是一个FrameLayout
.XXX.XXX.ShadowLayout2 android:layout_width="wrap_content" android:layout_height="wrap_content"> "200dp" android:layout_height="100dp" android:background="#6c6b6b" android:gravity="center" android:text="测试阴影"/> .XXX.XXX.ShadowLayout2>
附上全部代码
import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.support.v4.content.ContextCompat;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.View;import android.widget.FrameLayout;import android.widget.RelativeLayout;import com.benqu.wuta.R;/** * 控件阴影效果,只是最外层空间加阴影,不处理内部子控件 * 使用 Paint.setShadowLayer(),这是一个Layout, * 思路: 比如你有一个 200dp*100dp的矩形空间需要显示边界阴影,先通过计算onLayout,给这个区域设置padding * 这个padding的目的是给阴影留下位置,阴影区域的大小是原空间的大小 * 这里默认处理的是设置右边和下边的模糊阴影 * 当然,通过修改onDraw 里的代码,可以实现圆形边界阴影,圆角矩形边界阴影,Bitmap的边界阴影等等。。。 * Created by slack * on 17/9/25 下午1:28 */public class ShadowLayout2 extends FrameLayout { private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private RectF mRectF = new RectF(); /** * 阴影的颜色, 需要带透明 */ private int mShadowColor = Color.argb(128, 249, 94, 94); /** * 阴影的大小范围 radius越大越模糊,越小越清晰 */ private float mShadowRadius = 10; /** * 阴影的宽度,比如底部的阴影,那就是底部阴影的高度 */ private float mShadowWidth = 15; /** * 阴影 x 轴的偏移量, 计算padding时需要计算在内 */ private float mShadowDx = 0; /** * 阴影 y 轴的偏移量,计算padding时需要计算在内,比如想底部的阴影多一些,这个设置值就可以了 */ private float mShadowDy = 10; public ShadowLayout2(Context context) { this(context, null); } public ShadowLayout2(Context context, AttributeSet attrs) { this(context, attrs, 0); } public ShadowLayout2(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(attrs); } /** * 为 ShadowLayout 设置 Padding 以为显示阴影留出空间 */ private void resetShadowPadding() { float rectLeft = 0; float rectTop = 0; float rectRight = 0; float rectBottom = 0; int paddingLeft = 0; int paddingTop = 0; int paddingRight = 0; int paddingBottom = 0; // todo 测试代码,待完善,暂时是右侧和底部的阴影 rectRight = this.getWidth() - mShadowWidth - mShadowDx; paddingRight = (int) mShadowWidth + (int) mShadowDx; rectBottom = this.getHeight() - mShadowWidth - mShadowDy; paddingBottom = (int) mShadowWidth + (int) mShadowDy; mRectF.left = rectLeft; mRectF.top = rectTop; mRectF.right = rectRight; mRectF.bottom = rectBottom; this.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); } /** * 决定View在ViewGroup中的位置 , 此处left ,top...是相对于父视图 */ @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); resetShadowPadding(); } /** * 决定View的大小 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } /** * 如何绘制这个View, 真正绘制阴影的方法 */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawRect(mRectF, mPaint); } /** * 读取设置的阴影的属性 * * @param attrs 从其中获取设置的值 */ private void init(AttributeSet attrs) { setLayerType(View.LAYER_TYPE_SOFTWARE, null); // 关闭硬件加速,setShadowLayer 才会有效 this.setWillNotDraw(false); // 调用此方法后,才会执行 onDraw(Canvas) 方法 // todo 从AttributeSet获取设置的值 mPaint.setAntiAlias(true); mPaint.setColor(Color.TRANSPARENT); mPaint.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, mShadowColor); }}
更多相关文章
- 不用线程做Android软件欢迎界面,透明效果,完成后自动跳转
- Android堆内存也可自己定义大小
- android:theme 与 setTheme()设置透明效果并不同
- Android手势密码LockPatternView、LockPasswordUtils、LockPatte
- android v7兼容包RecyclerView的使用(三)——布局管理器的使用
- Android(安卓)SwipeMenuListView
- ym—— Android(安卓)5.0学习之感想篇(含Demo)
- 仿MIUI的Toast动画效果实现
- 关于GridView宽高的问题(转载rain的文章)