利用反射設(shè)置CardView陰影顏色

我們知道默認的CardView是不能設(shè)置陰影顏色的,許多時候卻又有這種需求秒啦,然后百度上解決方案很少潜慎,基本就是把官方的CardView的源碼改了再拷進工程嗽测。

看看效果:
反射修改的缺點和上面改源碼的缺點一樣,都是沒有Android5.0以上的View自帶的陰影繪制那么平滑好看蓉坎,且有半徑限制澳眷,如圖,TextViewApi21以上自帶陰影蛉艾,CardView是反射修改的陰影钳踊。

先看看CardView源碼:

可以發(fā)現(xiàn),
CardView屬性有關(guān)(setCardBackgroundColor,setCardElevation等)的基本都在靜態(tài)常量IMPL上了勿侯,
CardView里也沒有繪制陰影的相關(guān)方法拓瞪,所以陰影繪制很可能在IMPL里,
IMPL的類型CardViewImpl本身是個接口助琐,所以要找到它的子類祭埂,看他在哪里被賦值。


可以看到兵钮,IMPL根據(jù)android版本的不同被賦于了不同的 子類沟堡,
從名字也可以看出,其實這個就是為了實現(xiàn)不同Android版本的兼容和優(yōu)化矢空。
然后需要進入
CardViewApi21Impl.java
CardViewApi17Impl.java
CardViewBaseImpl.java
三個地方分別看看他們的區(qū)別航罗,
可以看出,
Android 5.0(CardViewApi21Impl.java)以上是調(diào)用View里面的陰影繪制的屁药。
Android 4.2(CardViewBaseImpl.java)以下是利用Drawable來繪制陰影的
Android 4.2-5.0(CardViewApi17Impl.java)只在CardViewBaseImpl.java的基礎(chǔ)上替換了畫圓角矩形的方法粥血。

Android 5.0(CardViewApi21Impl.java)的 View里面的陰影繪制過于復(fù)雜(可能調(diào)用native方法),用反射也不一定能完成酿箭,就沒有深入了复亏,
所以這里考慮用修改Drawable的屬性來實現(xiàn)修改陰影顏色。
帶陰影的圓角矩形 的Drawable 它已經(jīng)寫好了缭嫡,

進去RoundRectDrawableWithShadow類可以看到陰影的起始顏色和結(jié)束顏色兩個屬性缔御,但是是private的,所以我們要利用反射修改他的屬性值就行了妇蛀。

修改完mShadowStartColor,mShadowEndColor發(fā)現(xiàn):
什么都沒發(fā)生耕突?笤成?
當(dāng)然,因為IPML仍然是Api21以上的實現(xiàn)CardViewApi21Impl眷茁,用的是View的陰影繪制
所以需要先把它改成Api17的實現(xiàn)CardViewApi17Impl炕泳,才是用Drawable實現(xiàn)陰影。
所以要在之前加一步替換IPML和調(diào)用初始化IPML的方法上祈。


import android.os.Build;
import android.support.v7.widget.CardView;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class CardUtils {
    private static boolean inited=false;
    //設(shè)置obj的成員變量
    private static void setMember(Object obj, String memberName, Object value) {
        try {
            if (obj instanceof Class) {
                //靜態(tài)變量
                Field declaredField = ((Class) obj).getDeclaredField(memberName);
                declaredField.setAccessible(true);
                declaredField.set(null, value);
            } else {
                Field declaredField = obj.getClass().getDeclaredField(memberName);
                declaredField.setAccessible(true);
                declaredField.set(obj, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void init() {
        if (Build.VERSION.SDK_INT >= 21&&!inited) {
            inited=true;
            try {
                //new 一個CardViewApi17Impl
                Constructor<?> constructor = Class.forName("android.support.v7.widget.CardViewApi17Impl").getDeclaredConstructor();
                constructor.setAccessible(true);
                Object impl = constructor.newInstance();

                //用新的代替掉原來的
                setMember(CardView.class, "IMPL", impl);

                //執(zhí)行方法IMPL.initStatic()
                Method initStatic = impl.getClass().getDeclaredMethod("initStatic");
                initStatic.setAccessible(true);
                initStatic.invoke(impl);

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    public static void setCardShadowColor(CardView cardView, int startColor, int endColor) {
        try {
            //獲取背景
            Object background = cardView.getBackground();
            //設(shè)置顏色
            setMember(background, "mShadowStartColor", startColor);
            setMember(background, "mShadowEndColor", endColor);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

CardUtils.init()
最好是在Application啟動時調(diào)用培遵。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市登刺,隨后出現(xiàn)的幾起案子籽腕,更是在濱河造成了極大的恐慌,老刑警劉巖纸俭,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件节仿,死亡現(xiàn)場離奇詭異,居然都是意外死亡掉蔬,警方通過查閱死者的電腦和手機廊宪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來女轿,“玉大人箭启,你說我怎么就攤上這事◎燃#” “怎么了傅寡?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長北救。 經(jīng)常有香客問我荐操,道長,這世上最難降的妖魔是什么珍策? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任托启,我火速辦了婚禮,結(jié)果婚禮上攘宙,老公的妹妹穿的比我還像新娘屯耸。我一直安慰自己,他們只是感情好蹭劈,可當(dāng)我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布疗绣。 她就那樣靜靜地躺著,像睡著了一般铺韧。 火紅的嫁衣襯著肌膚如雪多矮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天哈打,我揣著相機與錄音塔逃,去河邊找鬼讯壶。 笑死,一個胖子當(dāng)著我的面吹牛患雏,可吹牛的內(nèi)容都是我干的鹏溯。 我是一名探鬼主播罢维,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼淹仑,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了肺孵?” 一聲冷哼從身側(cè)響起匀借,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎平窘,沒想到半個月后吓肋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡瑰艘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年是鬼,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片紫新。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡均蜜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出芒率,到底是詐尸還是另有隱情囤耳,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布偶芍,位于F島的核電站充择,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏匪蟀。R本人自食惡果不足惜椎麦,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望材彪。 院中可真熱鬧铃剔,春花似錦、人聲如沸查刻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽穗泵。三九已至普气,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間佃延,已是汗流浹背现诀。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工夷磕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人仔沿。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓坐桩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親封锉。 傳聞我的和親對象是個殘疾皇子绵跷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容

  • ¥開啟¥ 【iAPP實現(xiàn)進入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,365評論 0 17
  • 當(dāng)你的設(shè)計師要求你在某個 View 上增加陰影效果净当,那你只需要認真閱讀本文,陰影的問題就不再是問題蕴潦。 一像啼、前言 設(shè)...
    承香墨影閱讀 2,775評論 2 29
  • afinalAfinal是一個android的ioc,orm框架 https://github.com/yangf...
    passiontim閱讀 15,408評論 2 45
  • 步韻李文朝會長《戊戌詠春》 戊戍變法不惜身潭苞,君子成仁垂世綸忽冻。 甲午凄風(fēng)祭遠志,丙申長劍戮賊人萄传。 承前啟后中國夢甚颂,繼...
    白云之外閱讀 233評論 0 1
  • 我的男朋友很好,我要好好愛他秀菱,希望他也能一直好好愛我
    精品豬的謝大妹閱讀 102評論 0 0