原始碼系列篇之CardView

2021-08-14 03:49:55 字數 4792 閱讀 3324

周五的節奏真的心情爽啊,看看書啊,看看原始碼啊,時間都這樣毫不經意間過去了,爽啦啦!題外話就不說那麼多了啊。下面進入正題,帶你分析cardview這種帶陰影、圓角的view是怎麼一步步的實現的。

來看看cardview構造器吧:

public

cardview(context context)

public

cardview(context context, attributeset attrs)

public

cardview(context context, attributeset attrs, int defstyleattr)

哈哈哈,還是逃不過自定義view的法則啊。再去看看initialize方法吧:

private

void

initialize(context context, attributeset attrs, int defstyleattr) else

float radius = a.getdimension(r.styleable.cardview_cardcornerradius, 0);

float elevation = a.getdimension(r.styleable.cardview_cardelevation, 0);

float maxelevation = a.getdimension(r.styleable.cardview_cardmaxelevation, 0);

mcompatpadding = a.getboolean(r.styleable.cardview_cardusecompatpadding, false);

mpreventcorneroverlap = a.getboolean(r.styleable.cardview_cardpreventcorneroverlap, true);

int defaultpadding = a.getdimensionpixelsize(r.styleable.cardview_contentpadding, 0);

mcontentpadding.left = a.getdimensionpixelsize(r.styleable.cardview_contentpaddingleft,

defaultpadding);

mcontentpadding.top = a.getdimensionpixelsize(r.styleable.cardview_contentpaddingtop,

defaultpadding);

mcontentpadding.right = a.getdimensionpixelsize(r.styleable.cardview_contentpaddingright,

defaultpadding);

mcontentpadding.bottom = a.getdimensionpixelsize(r.styleable.cardview_contentpaddingbottom,

defaultpadding);

if (elevation > maxelevation)

musersetminwidth = a.getdimensionpixelsize(r.styleable.cardview_android_minwidth, 0);

musersetminheight = a.getdimensionpixelsize(r.styleable.cardview_android_minheight, 0);

a.recycle();

//這個地方很重要,這裡我們重點看

impl.initialize(mcardviewdelegate, context, backgroundcolor, radius,

elevation, maxelevation);

}

在這裡看到有乙個變數impl,那去看看該變數是在哪生成的吧:

private

static

final cardviewimpl impl;

static else

if (build.version.sdk_int >= 17) else

impl.initstatic();

}

這裡有幾個版本的分支,根據不同的版本生成不同的cardviewimpl,其實看設計模式的筒子們。這裡是工廠模式的一種,根據不同的情況生產不同的cardviewimpl(介面),那咋們先去看高版本的吧:

cardviewapi21實現類,還是照常跟進cardviewapi21initialize方法:

@override

public

void

initialize(cardviewdelegate cardview, context context,

colorstatelist backgroundcolor, float radius, float elevation, float maxelevation)

這裡cardview是什麼東東啊,別急,咱們回到cardview類中去看看就知道了啊

private

final cardviewdelegate mcardviewdelegate = new cardviewdelegate()

@override

public

boolean

getusecompatpadding()

@override

public

boolean

getpreventcorneroverlap()

@override

public

void

setshadowpadding(int left, int top, int right, int bottom)

@override

public

void

setminwidthheightinternal(int width, int height)

if (height > musersetminheight)

}@override

public drawable getcardbackground()

@override

public view getcardview()

};

可以看到它是cardview內部的乙個final型別的內部類啊,這裡主要是來看下setcardbackground方法,這裡是將impldrawable回傳過來了,該處也沒做什麼,只是呼叫了cardviewsetbackgrounddrawable方法啊,也即是我們的viewgroupsetbackgrounddrawable方法。看過設計模式的朋友其實不難發現,mcardviewdelegate內部類是不是builder的設計模式呢,builder設計模式最大的特點就是將外部類的一些行為封裝到內部類中。其實如果外部類的屬性不是很多的話,也沒必要封裝成builder模式。你們覺得呢?

上面提到了cardviewapi21initialize方法中roundrectdrawable變數,也提到了它是乙個drawable,那咱們看看是怎麼自定義乙個drawable吧:

1.對roundrectdrawable的大小進行修正啊:

@override

protected

void

onboundschange(rect bounds)

private

void

updatebounds(rect bounds)

mboundsf.set(bounds.left, bounds.top, bounds.right, bounds.bottom);

mboundsi.set(bounds);

//預設是true的

if (minsetforpadding)

}

上面對mboundsi通過paddingmradius縮小,mboundsf同樣也是縮小。

下面是對roundrectdrawable的繪製部分了,繪製的話,就簡單了:

@override

public

void

draw(canvas canvas) else

//繪製帶圓角的矩形

canvas.drawroundrect(mboundsf, mradius, mradius, paint);

if (clearcolorfilter)

}

這裡只是分析21之上的**,具體低版本的**看下cardviewjellybeanmr1cardviewgingerbread

鴻蒙原始碼分析系列篇

鴻蒙核心原始碼注釋中文版 gitee倉 csdn倉 github倉 coding倉 專案中文註解鴻蒙官方核心原始碼,詳細闡述鴻蒙架構和 設計細節,精讀核心原始碼最大的好處是 將孤立知識點織成一張高濃度,高密度底層網,對計算機體系化理解形成永久記憶,從此高屋建瓴分析 解決問題.鴻蒙原始碼分析系列篇 c...

Android原始碼分析系列 整理篇

本系列主要走了一下android掛載sd卡的流程,從vold到framework,再從framework到ui。也熟悉了谷歌寫的c c 源 提高一下自己的類的設計與 的技巧,很感謝谷歌提供這麼乙個手機的開源作業系統android,讓鄙人也有機會來了解一下智慧型終端系統的實現原理。只要有c c 的基礎...

Android原始碼分析系列 整理篇

本系列主要走了一下android掛載sd卡的流程,從vold到framework,再從framework到ui。也熟悉了谷歌寫的c c 源 提高一下自己的類的設計與 的技巧,很感謝谷歌提供這麼乙個手機的開源作業系統android,讓鄙人也有機會來了解一下智慧型終端系統的實現原理。只要有c c 的基礎...