android 阴影的实现方式

作者: 刘景昌 | 来源:发表于2019-05-13 16:03 被阅读220次

    在开发过程中一般情况下,UI设计师喜欢添加一些阴影来使控件看起来比较有立体和层次感,来表明自己高大上的设计。
    在这里分享下android里面关于阴影的实现方式:
    1.使用.9文件
    优点:个人认为最好的实现方式 实现方便 节省内存和渲染时间,使用方便
    缺点:每个阴影都用.9文件会增加报的体积大小而且不如自己写的好维护 总不能每次换点阴影都去找UI
    2.使用 layer-list
    实现原理:layer-list本身是一些drawable的集合 我们把许多的drawable叠加起来形成层次差实现阴影
    使用layer-list实现 阴影边框效果:

    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <!--第一层阴影-->
        <item>
            <shape android:shape="rectangle">
                <solid android:color="#0F000000" />
                <corners android:radius="10dp" />
            </shape>
        </item>
        <!--第二层前景-->
        <item
            android:bottom="1dp"
            android:left="1dp"
            android:right="1dp"
            android:top="1dp">
            <shape android:shape="rectangle">
                <solid android:color="@android:color/white"/>
                <corners android:radius="10dp" />
            </shape>
        </item>
    </layer-list>
    

    实现效果:


    image.png

    我们可以看到最终的实现效果并不是很理想,但是如果UI要求的效果不是很严格的话还是勉强能用的

    优点:书写比较方便 可以使用渐变来替换阴影 如果颜色统一的方便管理
    缺点:增加背景图层 可以实现阴影效果 但是没有模糊
    3.使用 elevation,translationZ
    android 5.0以后增加的设置阴影的api 并配合OutlineProvider 修改阴影的轮廓
    android 8.0以后增加两个api可以修改阴影的颜色 8.0一下无效
    android:outlineAmbientShadowColor :照射光的颜色 一般没什么作用
    android:outlineSpotShadowColor:阴影颜色
    实现效果:


    image.png

    注意点:使用阴影颜色的时候要使用8位的色值 一定要带透明度哦 否则是没有效果的
    优点: 使用自带的api不用添加多余的drawable文件 并且支持 translationZ 动画方便实现点击的动画效果
    缺点:只有api28以上才可以使用
    4.使用自定义View 和自定义ViewGrop
    为什么会是两种呢?不是只用ViewGrop就行了吗?
    我认为对于功能比较单一 或定制化比较高的话,还是多写一个自定义View比较合适 毕竟可以减少一层的布局结构 而自定义ViewGrop 更加偏向于通用化。
    在自定义View中实现阴影主要有两种方式
    (1)使用BlurMaskFilter:模糊遮罩滤镜 改变图像的透明度值来实现的
    核心代码: mBlurMaskFilter = new BlurMaskFilter(mMaskRadius, BlurMaskFilter.Blur.NORMAL);
    mMaskPaint.setMaskFilter(mBlurMaskFilter);
    参数:mMaskRadius:扩散的半径
    BlurMaskFilter.Blur.NORMAL:整个图像都被模糊掉
    BlurMaskFilter.Blur.SOLID:图像边界外产生一层与图像颜色一致阴影效果
    BlurMaskFilter.Blur.OUTER:图像边界外产生一层阴影,并且将图像变成透明效果
    BlurMaskFilter.Blur.INNER:在图像内部边沿产生模糊效果
    他可以让背景和阴影都出现渐变色的效果效果比较好看
    实现效果


    image.png
    注意:使用paint.setMaskFilter()需要将硬件加速关闭 一般在自定义View的构造方法调用就行了 setLayerType(View.LAYER_TYPE_SOFTWARE,null)
    优点:可以较好的实现一个扩散阴影的效果,可以支持阴影使用渐变色,也可以是图片颜色的延伸
    缺点: 需要关闭硬件加速,暂时不支持阴影偏移
    最终实现的View
    <com.example.shadowlibrary.MaskTextView
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:layout_gravity="center_horizontal"
                android:layout_marginStart="20dp"
                android:layout_marginTop="20dp"
                android:layout_marginEnd="20dp"
                app:shadowText="自定义View实现阴影" />
    

    自定义属性的介绍:
    shadowTextColor :文字颜色
    shadowBgStartColor:背景渐变开始颜色
    shadowBgEndColor:背景渐变结束颜色
    shadowSelectStartColor:点击后背景渐变开始颜色
    shadowSelectEndColor:点击后背景渐变结束颜色
    shadowTextRadius:背景圆角
    shadowTextSize:背景字体大小
    (2)使用 setShadowLayer
    核心代码:mMaskPaint.setShadowLayer(radius,dx,dy,color));
    参数:radius 阴影的扩散半径
    dx 阴影X方向偏移
    dy 阴影Y方向偏移
    color 阴影颜色
    可以是背景产生阴影的而效果
    实现效果:

    image.png
    注意:使用paint.setShadowLayer()需要将硬件加速关闭
    优点:可以实现一般情况下所有的阴影效果 支持阴影偏移
    缺点: 需要关闭硬件加速
    自定义ViewGrop的引用代码:
        <com.example.shadowlibrary.MaskViewGroup
                android:layout_width="match_parent"
                android:layout_height="150dp"
                android:layout_gravity="center_horizontal"
                android:layout_marginStart="10dp"
                android:layout_marginTop="10dp"
                android:layout_marginEnd="10dp"
                android:layout_marginBottom="20dp"
                app:containerCornerRadius="27dp"
                app:containerDeltaLength="10dp"
                app:containerShadowColor="@color/colorE9E9E9"
                app:containerShadowRadius="6dp"
                app:deltaX="0dp"
                app:deltaY="-3dp"
                app:enable="true">
    
                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@drawable/shape_27_white"
                    android:gravity="center" />
            </com.example.shadowlibrary.MaskViewGroup>
    

    自定义属性介绍:
    containerShadowColor:阴影颜色
    containerShadowRadius:阴影半径
    containerCornerRadius:阴影圆角
    containerDeltaLength:阴影到边框距离
    deltaX:阴影X方向偏移
    deltaY:阴影Y
    enable:是否显示阴影

    过程中碰到的一点小坑:
    为了防止onTouchEvent与onClick冲突
    注意:重写performClick方法并在onTouchEvent调用
    @Override
    public boolean performClick() {
    return super.performClick();
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
    return true;
    case MotionEvent.ACTION_UP:
    performClick();
    return true;
    case MotionEvent.ACTION_CANCEL:
    return true;
    }
    return super.onTouchEvent(event);
    }

    自定义View 的GitHub 地址:https://github.com/525642022/shadwoView

    相关文章

      网友评论

        本文标题:android 阴影的实现方式

        本文链接:https://www.haomeiwen.com/subject/hqaloqtx.html