Android陰影背景的實(shí)現(xiàn)

一泡态、需求來(lái)源:

設(shè)計(jì)師要求還原設(shè)計(jì)的陰影苦囱,下面是sketch原型參數(shù):

圓角:8px

外陰影:                    
Offset:     0px     1px                         
             X       Y              

Effect:     10px    0px                 
            Blur    Spread                  

顏色:      #135B90D0                       

二疚宇、Android本身控件自帶陰影效果無(wú)法還原

Google的Material Design中對(duì)于陰影的定義是:海拔高度是相對(duì)深度或距離籽腕,是兩個(gè)表面在 Z 軸上的距離乾蓬。

實(shí)現(xiàn)方式:

  • 第一種方式:elevation屬性
    View的大小位置都是通過(guò)x,y確定的渊抄,而現(xiàn)在有了z軸的概念尝胆,而這個(gè)z值就是View的高度(elevation)丧裁,而高度決定了陰影(shadow)的大小护桦。

  • 第二種方式:CardView自帶屬性

card_view:cardElevation 陰影的大小
card_view:cardMaxElevation 陰影最大高度
card_view:cardBackgroundColor 卡片的背景色
card_view:cardCornerRadius 卡片的圓角大小
card_view:contentPadding 卡片內(nèi)容于邊距的間隔
  • 第三種方式:
    設(shè)置邊框?yàn)閟hape,通過(guò)layer-list實(shí)現(xiàn)層次感
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape android:shape="oval">
        <padding
            android:bottom="2dp"
            android:left="2dp"
            android:right="2dp"
            android:top="2dp" />
        <solid android:color="#0DF3F3F3" />
        <corners android:radius="8dp" />
    </shape>
</item>
    <item>
        <shape
            android:layout_width="wrap_content"
            android:shape="oval">
            <padding
                android:bottom="2dp"
                android:left="2dp"
                android:right="2dp"
                android:top="2dp" />
            <solid android:color="#10F3F3F3" />
            <corners android:radius="8dp" />
        </shape>
    </item>
<item>
    <shape android:shape="oval">
        <padding
            android:bottom="2dp"
            android:left="2dp"
            android:right="2dp"
            android:top="2dp" />
        <solid android:color="#15F3F3F3" />
        <corners android:radius="8dp" />
    </shape>
</item>
<item>
    <shape android:shape="oval">
        <padding
            android:bottom="2dp"
            android:left="2dp"
            android:right="2dp"
            android:top="2dp" />
        <solid android:color="#20F3F3F3" />
        <corners android:radius="8dp" />
    </shape>
</item>
<item>
    <shape android:shape="oval">
        <padding
            android:bottom="2dp"
            android:left="2dp"
            android:right="2dp"
            android:top="2dp" />
        <solid android:color="#25F3F3F3" />
        <corners android:radius="8dp" />
    </shape>
</item>
<item>
    <shape android:shape="oval">
        <solid android:color="#FFFFFF" />
    </shape>
</item>
</layer-list>

三煎娇、使用Android畫筆Paint來(lái)實(shí)現(xiàn)

  • 第四種方式(屬性一一對(duì)應(yīng)設(shè)計(jì)稿):
/**
 * 使用圓角時(shí)二庵,應(yīng)設(shè)置圓角相同的background
 */

public class ShadowRelativeLayout extends RelativeLayout {
    /**
     * 陰影的顏色
     */
    private int shadowColor = Color.argb(90, 0, 0, 0);
    /**
     * 高斯模糊的模糊半徑,值越大越模糊,越小越清晰,
     */
    private float shadowBlur = 30;
    /**
     * 陰影的圓角
     */
    private float shadowRadius = 0;

    /**
     * 陰影的偏移
     */
    private float shadowDx = 0;
    private float shadowDy = 0;

    public ShadowRelativeLayout(@NonNull Context context) {
        this(context, null);
    }

    public ShadowRelativeLayout(@NonNull Context context,
                                @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ShadowRelativeLayout(@NonNull Context context, @Nullable AttributeSet attrs,
                                int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        dealAttrs(context, attrs);
        setPaint();
    }

    private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    @Override
    public void draw(Canvas canvas) {
        setInsetBackground();
        canvas.drawRoundRect(getRectF(), shadowRadius, shadowRadius, mPaint);
        super.draw(canvas);
    }

    private boolean setInsetBackground() {
        Drawable background = getBackground();
        if (background == null || background instanceof InsetDrawable) {
            return false;
        }
        InsetDrawable drawable =
                new InsetDrawable(background, getPaddingLeft(), getPaddingTop(),
                        getPaddingRight(), getPaddingBottom());
        setBackground(drawable);
        return true;
    }

    private RectF getRectF() {
        return new RectF(getPaddingLeft() + shadowDx, getPaddingTop() + shadowDy,
                getWidth() - getPaddingRight() + shadowDx,
                getHeight() - getPaddingBottom() + shadowDy);
    }

    private void dealAttrs(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadowRelativeLayout);
        if (typedArray != null) {
            shadowColor = typedArray.getColor(R.styleable.ShadowRelativeLayout_shadow_color, shadowColor);
            shadowRadius =
                    typedArray.getDimension(R.styleable.ShadowRelativeLayout_shadow_radius, shadowRadius);
            shadowBlur =
                    typedArray.getDimension(R.styleable.ShadowRelativeLayout_shadow_blur, shadowBlur);
            shadowDx = typedArray.getDimension(R.styleable.ShadowRelativeLayout_shadow_dx, shadowDx);
            shadowDy = typedArray.getDimension(R.styleable.ShadowRelativeLayout_shadow_dy, shadowDy);
            typedArray.recycle();
        }
    }

    private void setPaint() {
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);  // 關(guān)閉硬件加速,陰影才會(huì)繪制
        // todo 從AttributeSet獲取設(shè)置的值
        mPaint.setAntiAlias(true);
        mPaint.setColor(shadowColor);
        mPaint.setMaskFilter(new BlurMaskFilter(shadowBlur, BlurMaskFilter.Blur.NORMAL));
    }

    @Override
    public boolean isOpaque() { //純色或圖片做背景時(shí),draw之前會(huì)有黑底色缓呛,
        return false;
    }
}

attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ShadowRelativeLayout">
        <attr format="color" name="shadow_color"/>
        <attr format="dimension" name="shadow_radius"/>
        <attr format="dimension" name="shadow_blur"/>
        <attr format="dimension" name="shadow_dx"/>
        <attr format="dimension" name="shadow_dy"/>
    </declare-styleable>
</resources>

使用范例(屬性完美映射設(shè)計(jì)稿):

<ShadowRelativeLayout
    android:layout_width="180dp"
    android:layout_height="100dp"
    android:background="@drawable/shape_round_white_dp8"
    android:padding="10dp"
    bind:shadow_blur="10dp"
    bind:shadow_color="#135B90D0"
    bind:shadow_dx="0dp"
    bind:shadow_dy="1dp"
    bind:shadow_radius="8dp">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_gravity="center"
        android:scaleType="center"
        android:src="@drawable/light" />
</ShadowRelativeLayout>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末催享,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子哟绊,更是在濱河造成了極大的恐慌因妙,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件票髓,死亡現(xiàn)場(chǎng)離奇詭異攀涵,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)洽沟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)裆操,“玉大人炉媒,你說(shuō)我怎么就攤上這事昆烁〉踔瑁” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵静尼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我茅郎,道長(zhǎng),這世上最難降的妖魔是什么系冗? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任奕扣,我火速辦了婚禮,結(jié)果婚禮上掌敬,老公的妹妹穿的比我還像新娘惯豆。我一直安慰自己奔害,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布芯杀。 她就那樣靜靜地躺著雅潭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪扶供。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天太援,我揣著相機(jī)與錄音扳碍,去河邊找鬼提岔。 笑死左腔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的振亮。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼麸祷,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼褒搔!你這毒婦竟也來(lái)了阶牍?” 一聲冷哼從身側(cè)響起星瘾,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎琳状,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體困食,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡翎承,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年叨咖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了瘩例。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芒澜。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡痴晦,死狀恐怖琳彩,靈堂內(nèi)的尸體忽然破棺而出誊酌,到底是詐尸還是另有隱情露乏,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布箱锐,位于F島的核電站劳较,受9級(jí)特大地震影響浩聋,放射性物質(zhì)發(fā)生泄漏臊恋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一抖仅、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧环凿,春花似錦放吩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)环肘。三九已至集灌,卻和暖如春悔雹,著一層夾襖步出監(jiān)牢的瞬間欣喧,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工益涧, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留驯鳖,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓扭弧,卻偏偏與公主長(zhǎng)得像记舆,于是被迫代替她去往敵國(guó)和親鸽捻。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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

  • 當(dāng)你的設(shè)計(jì)師要求你在某個(gè) View 上增加陰影效果摘能,那你只需要認(rèn)真閱讀本文敲街,陰影的問(wèn)題就不再是問(wèn)題。 一逻恐、前言 設(shè)...
    承香墨影閱讀 2,775評(píng)論 2 29
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程峻黍,因...
    小菜c閱讀 6,365評(píng)論 0 17
  • CardView 擴(kuò)展 FrameLayout 類并讓您能夠顯示卡片內(nèi)的信息,這些信息在整個(gè)平臺(tái)中擁有一致的呈現(xiàn)方...
    輕云時(shí)解被占用了閱讀 6,826評(píng)論 4 22
  • 幾年前在本雜志上看到的一則故事一直迄今記憶深刻挽拂,那些觸動(dòng)心靈的瞬間就像是在最深的絕望里遇見(jiàn)最美的風(fēng)景骨饿,令你念念不忘...
    小蠻婆顏究社閱讀 342評(píng)論 2 10
  • 我見(jiàn)過(guò)許多優(yōu)秀的人。 生命的美麗之處都源自于苦難绒北,那些惡意的能量,可笑的境遇闷游。因?yàn)楹筒灰粯拥娜烁衽鲎不福圆艜?huì)有了...
    靈翼之光閱讀 226評(píng)論 0 0