您当前的位置: 首页 >  ui

命运之手

暂无认证

  • 4浏览

    0关注

    747博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【高级UI】【022】Android手写阴影效果

命运之手 发布时间:2021-11-17 17:20:03 ,浏览量:4

前言

安卓实现阴影大致有三种方式

  • 使用View自带的elevation属性产生阴影效果
  • TextView可通过shadowColor,shadowRadius,shadowDx,shadowDy来控制阴影
  • 使用Paint的setShadowLayer功能,绘图的同时绘制阴影
  • 通过BlurMaskFilter给Paint设置蒙板滤镜,达到模糊效果,从而画出阴影

其中,第三种是一种最具通用性的方案,它代表了阴影效果的底层实现方式

它不仅适用于安卓,在其它语言中,一般也有类似API与之对应,所以掌握这种方式,对我们长远发展很有帮助

使用elevation属性

elevation有提升高度的意思,控件高度提升后,就会在下方产生阴影效果,这是SDK内部已经实现的功能

这里主要讲解下,elevation属性在使用时的注意事项

  • elevation值越大,则根据光线效果,产生的阴影面积越大
  • 阴影范围肯定比控件范围大,因为View不能铺满父容器,一定要小于父容器,才能看到阴影效果
  • outlineSpotShadowColor可以指定阴影颜色
  • outlineProvider可以指定阴影范围,none无阴影,bounds沿控件边界生成阴影,paddedBounds除去padding部分,根据内容边界生成阴影,background根据背景轮廓产生阴影
  • 当outlineProvider=background时,必须指定背景,否则无法产生阴影

使用ShadowLayer

ShadowLayer是SDK内部为Paint提供的快捷功能,它允许在绘图的同时,自动生成对应轮廓的阴影

为了提高复用性,我们这里不自定义View,而是将阴影功能封装到一个Drawable里面,这样任何View都能使用


	package com.android.architecture;
	
	import android.graphics.Canvas;
	import android.graphics.ColorFilter;
	import android.graphics.LinearGradient;
	import android.graphics.Paint;
	import android.graphics.PixelFormat;
	import android.graphics.PorterDuff;
	import android.graphics.PorterDuffXfermode;
	import android.graphics.Rect;
	import android.graphics.Shader;
	import android.graphics.drawable.Drawable;
	
	import com.easing.commons.android.value.color.Colors;
	
	public class ShadowDrawable extends Drawable {
	
	    public final int[] solidColor;
	    public final int shadowColor;
	
	    public final int radius;
	    public final int dx;
	    public final int dy;
	
	    public final Paint solidPaint;
	    public final Paint shadowPaint;
	
	    public final Rect bounds = new Rect();
	
	    //ShadowLayer大小和位置计算方式
	    //每个像素向外扩展radius个像素,同时透明度逐渐变淡,产生模糊效果
	    //最后整个阴影图层再向右移动dx个像素,向下移动dy个像素
	    public ShadowDrawable(int[] solidColor, int shadowColor, int dx, int dy, int radius) {
	        this.solidColor = solidColor;
	        this.shadowColor = shadowColor;
	        this.dx = dx;
	        this.dy = dy;
	        this.radius = radius;
	        this.shadowPaint = new Paint();
	        this.solidPaint = new Paint();
	        //设置阴影画笔
	        shadowPaint.setAntiAlias(true);
	        shadowPaint.setColor(shadowColor);
	        shadowPaint.setStyle(Paint.Style.FILL);
	        shadowPaint.setShadowLayer(radius, dx, dy, shadowColor);
	    }
	
	    @Override
	    public void draw(Canvas canvas) {
	        canvas.drawRoundRect(bounds.left, bounds.top, bounds.right, bounds.bottom, radius, radius, shadowPaint);
	        canvas.drawRoundRect(bounds.left, bounds.top, bounds.right, bounds.bottom, radius, radius, solidPaint);
	    }
	
	    @Override
	    public void setBounds(int left, int top, int right, int bottom) {
	        bounds.left = left + radius;
	        bounds.top = top + radius;
	        bounds.right = right - radius - dx;
	        bounds.bottom = bottom - radius - dy;
	        //设置实心画笔
	        LinearGradient shader = new LinearGradient(
	                0, 0, bounds.width(), bounds.height(),
	                new int[]{solidColor[0], solidColor[1]},
	                new float[]{0.0F, 1.0F},
	                Shader.TileMode.CLAMP
	        );
	        solidPaint.setColor(Colors.BLACK);
	        solidPaint.setShader(shader);
	        solidPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
	        //重绘
	        invalidateSelf();
	    }
	
	    @Override
	    public void setAlpha(int alpha) {
	
	    }
	
	    @Override
	    public void setColorFilter(ColorFilter colorFilter) {
	
	    }
	
	    @Override
	    public int getOpacity() {
	        return PixelFormat.TRANSLUCENT;
	    }
	}


	Button view = new Button(ctx);
	view.setText("OK");
	view.setTextColor(Color.WHITE);
	Drawable drawable = new ShadowDrawable(new int[]{Colors.RED, Colors.ORANGE}, Colors.ORANGE, 10, 10, 20);
	view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
	view.setBackground(drawable);

在这里插入图片描述 通过BlurMaskFilter自己绘制阴影


	package com.android.architecture;
	
	import android.content.Context;
	import android.graphics.Bitmap;
	import android.graphics.BlurMaskFilter;
	import android.graphics.Canvas;
	import android.graphics.Paint;
	import android.graphics.Rect;
	import android.graphics.drawable.BitmapDrawable;
	import android.util.AttributeSet;
	
	import androidx.appcompat.widget.AppCompatImageView;
	
	@SuppressWarnings("all")
	public class A extends AppCompatImageView {
	
	    Paint paint;
	
	    int radius = 10;
	    int dx = 5;
	    int dy = 5;
	
	    public A(Context context) {
	        this(context, null);
	    }
	
	    public A(Context context, AttributeSet attributeSet) {
	        super(context, attributeSet);
	        init(context, attributeSet);
	    }
	
	    protected void init(Context context, AttributeSet attributeSet) {
	        setLayerType(LAYER_TYPE_SOFTWARE, null);
	        setImageResource(R.drawable.app_back_m02);
	        paint = new Paint();
	        BlurMaskFilter filter = new BlurMaskFilter(radius, BlurMaskFilter.Blur.NORMAL);
	        paint.setMaskFilter(filter);
	    }
	
	    @Override
	    protected void onDraw(Canvas canvas) {
	        BitmapDrawable drawable = (BitmapDrawable) getDrawable();
	        Bitmap bitmap = drawable.getBitmap();
	        Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
	        Rect dst1 = new Rect(100 + dx, 100 + dy, 400 + dx, 400 + dy);
	        Rect dst2 = new Rect(100, 100, 400, 400);
	        canvas.drawBitmap(bitmap, src, dst1, paint);
	        canvas.drawBitmap(bitmap, src, dst2, null);
	    }
	}



在这里插入图片描述 源码下载

Android实现阴影效果.zip

关注
打赏
1654938663
查看更多评论
立即登录/注册

微信扫码登录

0.0399s