CardView改变阴影颜色

项目GitHub地址 : CardViewShadowColor

  • CardView本身自带了灰色的阴影颜色,但是是不可修改的,而UI往往要求按钮的颜色是红色的就需要红色的阴影,在GitHub上搜索ShadowLayout等关键字,找到一些实现阴影的库,但有的效果不好,有性能有问题,会一直重绘,导致cpu及内存占用过高,界面卡顿,甚至OOM。

  • 之前一直百思不得其解,为什么不让CardView能自定义阴影颜色呢,看了源码才搞清楚意图,我猜测有两个原因:

  1. 因为不想让使用者随便改变阴影颜色,因为自然界中不管什么颜色的物体,其阴影都是灰色

  2. API >=21 View支持了阴影,只能在5.0以上的手机上生效,而API < 21 阴影都是重新绘制的,而View默认的阴影是灰色的,所以API < 21 重新绘制的阴影其颜色也给写死了灰色,且不提供public api供外接访问,应该是为了5.0以上手机使用阴影有更高的效率
     

    CardView values.xml文件
    <color name="cardview_shadow_end_color">#03000000</color>
    <color name="cardview_shadow_start_color">#37000000</color>
     
    RoundRectDrawableWithShadow(Resources resources, ColorStateList backgroundColor, float radius,
                float shadowSize, float maxShadowSize) {
        mShadowStartColor = resources.getColor(R.color.cardview_shadow_start_color);
        mShadowEndColor = resources.getColor(R.color.cardview_shadow_end_color);
           
    }
     

     

  3. 可以看出其实是支持自定义阴影颜色的,只不过在代码里给写死了,且未提供公开的api修改颜色的方法或属性
    static {
        if (Build.VERSION.SDK_INT >= 21) {
            IMPL = new CardViewApi21Impl();
        } else if (Build.VERSION.SDK_INT >= 17) {
            IMPL = new CardViewApi17Impl();
        } else {
            IMPL = new CardViewBaseImpl();
        }
        IMPL.initStatic();
    }
     

    直接改变values.xml中的cardview_shadow_end_color与cardview_shadow_start_color在5.0及以上的手机中是不生效的,因为5.0以上的手机,根本不创建RoundRectDrawableWithShadow类,而是使用View自带的阴影方法设置的,所以不管怎么改变一直是灰色阴影,所以要想在5.0及以上的手机上可以改变阴影颜色,可以修改下代码,如下所示:
     

    static {
        //if (Build.VERSION.SDK_INT >= 21) {
        //    IMPL = new CardViewApi21Impl();
        //} else 
        if (Build.VERSION.SDK_INT >= 17) {
            IMPL = new CardViewApi17Impl();
        } else {
            IMPL = new CardViewBaseImpl();
        }
        IMPL.initStatic();
    }

     

  4. 这样就可以强制使其执行RoundRectDrawableWithShadow类来绘制阴影,改的颜色值也就生效了

  5. 如果没有必须改变阴影颜色的需求,还是直接使用默认的,这样性能更好

  6. 为了更方便的使用支持改变阴影颜色的CardView,我基于CardView 24.2.1版本改写了支持改变阴影颜色的库, 为了和官方的CardView库共存,且不冲突,我把所有属性、color及style的命名都加了前缀yc,当然也可以单独使用,使用方式如下
    builb.gradle
     

    最好和官方的CardView库一起使用,不需要特殊修改阴影颜色的地方,使用官方的CardView,
    需要修改View阴影的地方才使用YcCardView
    implementation 'com.zyp.cardview:cardview:1.0.1'

    pom.xml
     

    <dependency>
      <groupId>com.zyp.cardview</groupId>
      <artifactId>cardview</artifactId>
      <version>1.0.1</version>
      <type>pom</type>
    </dependency>
     
        <!--android:foreground="@drawable/item_selector"  api>=21 ripper  api<21 selector-->
        <!--android:stateListAnimator="@drawable/state_list_animator" 点击动画效果 支持api>=21-->
        <!--CardView 默认使用-->
        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:clickable="true"
            android:focusable="true"
            android:foreground="@drawable/item_selector"
            android:stateListAnimator="@drawable/state_list_animator"
            app:cardBackgroundColor="@color/white"
            app:cardCornerRadius="5dp"
            app:cardElevation="5dp"
            app:cardMaxElevation="5dp"
            app:cardPreventCornerOverlap="false">
     
            <TextView
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:background="@null"
                android:gravity="center"
                android:text="Hello World!" />
        </android.support.v7.widget.CardView>
        <!--YcCardView的使用-->
        <!--ripper的范围无法控制-->
        <com.zyp.cardview.YcCardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:clickable="true"
            android:focusable="true"
            android:foreground="@drawable/item_selector"
            android:stateListAnimator="@drawable/state_list_animator"
            app:ycCardCornerRadius="5dp"
            app:ycCardElevation="5dp"
            app:ycCardMaxElevation="5dp"
            app:ycCardPreventCornerOverlap="true"
            app:ycStartShadowColor="@color/red">
            <!--只用设置开始颜色ycStartShadowColor,ycStartShadowColor默认值为#00ffffff 一般不用设置-->
     
            <TextView
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:gravity="center"
                android:text="Hello World!" />
        </com.zyp.cardview.YcCardView>
     
    复制代码

     

  7. 在引用第三方的UI库,特别是View绘制相关的,如果View本身没有变化,draw()方法却一直执行,这种问题就非常严重了,但是这种问题却是最好排查的,Android Studio自带的工具Android Device Monitor就可以轻松实现排查,如下图:
  8.  

     

     

     

     

    当然也可以使用Android Profiler,但是貌似不可以按照包名搜索。

     

     

     

     

     

    转载于:https://juejin.im/post/5ba5946ee51d450e925227b4

    相关资源:YCCardView,自定义阴影效果的控件,支持设置阴影偏移效果,支持设置扩散阴影,设置圆角大小,设置阴影颜色,还可以设置上下左右某个方法显示阴影效果,控件小巧但功能强大,方便维护和统一管理设置阴影操作。同时可以用于 RecyclerView项创建位图。

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值