不知道大家有沒有過這樣的煩惱,打開Drawable文件夾下到處都是各式各樣的shape定義,其中不乏有一模一樣的樣式,但只是名字不同,或者僅僅只是radius,color不同,但每次一有邊框,圓角,點(diǎn)擊效果等都需要定義一個(gè)新的shape,今天這個(gè)頁面圓角要2dp,明天一樣的又要4dp,或是顏色的變化都需要我們重新寫一個(gè)shape.xml,至少我每次寫的時(shí)候都有點(diǎn)受不了,為了避免每次這樣做重復(fù)的定義,這里為大家分享一個(gè)我用java代碼來控制shape的生成,動(dòng)態(tài)改變shape的樣式。

源碼地址
主要特性
- 不用再寫shape.xml文件了?。?!
- 鏈?zhǔn)秸{(diào)用
- 涵蓋Shape幾乎常用的所有屬性,如:TYPE,Radius,Stroke,Soild,Gradient,GradientType,GradientCenter,GradientRadius,Size
- 支持Selector
- 支持Layer-list
如何使用
1.ShapeBuilder
非常簡單,來看看最基本的使用方式,比如一個(gè)帶邊框的View。
ShapeBuilder.create()
.Type(RECTANGLE)
.Soild(Color.RED)
.Stroke(5,Color.BLACK)
.build(View);
設(shè)置對應(yīng)的屬性,調(diào)用build(View)傳入需要設(shè)置背景的view即可。如果需要獲得構(gòu)建的drawable可以調(diào)用該build()方法返回。
利用Builder模式,實(shí)現(xiàn)了一系列的鏈?zhǔn)秸{(diào)用,方便我們設(shè)置屬性值。
public interface IShape {
public ShapeBuilder Type(int type);
public ShapeBuilder Stroke(int px, int color);
public ShapeBuilder Stroke(int px, int color, int dashWidth, int dashGap);
public ShapeBuilder Solid(int color);
public ShapeBuilder Radius(float px);
public ShapeBuilder Radius(float topleft, float topright, float botleft, float botright);
public ShapeBuilder Gradient(int startColor, int centerColor, int endColor);
public ShapeBuilder Gradient(int angle, int startColor, int centerColor, int endColor);
public ShapeBuilder Gradient(GradientDrawable.Orientation orientation, int startColor, int
centerColor, int endColor);
public ShapeBuilder GradientType(int type);
public ShapeBuilder GradientCenter(float x, float y);
public ShapeBuilder GradientRadius(float radius);
public ShapeBuilder setSize(int width, int height);
public void build(View v);
public GradientDrawable build();
}
2.ShapeListBuilder替代Selector
其實(shí)這個(gè)是基于ShapeBuilder,將幾個(gè)主要的都順便封裝了一下,可以替代Selector的定義。
ShapeListBuilder.create(Drawable drawable)//傳默認(rèn)狀態(tài)下的drawable
.addShape(Drawable shape, int... state)//狀態(tài)對應(yīng)的drawable和state
.build(View view);

3.LayerBuilder替代Layer-list
用于替代Layer
LayerBuilder.create(Drawable... drawables)
.Bottom(1, 15)//top,right...setInset等
.build(View view);
用法其實(shí)都比較簡單無腦,記住要最后調(diào)用build(View view)方法~
原理
原理其實(shí)也比較基礎(chǔ),我們每次定義Shape文件,其實(shí)最后會(huì)被生成GradientDrawable,通過查看GradientDrawable源碼,我們其實(shí)能看到我們定義的type,Radius,solid等屬性其實(shí)就是最后在這里面通過TypeArray讀取出來,最后生成了GradientDrawable對象,所以我們只是需要對GradientDrawable源碼進(jìn)行閱讀理解,考慮到GradientDrawable屬性眾多這一特點(diǎn),利用Build模式進(jìn)行封裝,便實(shí)現(xiàn)了ShapeBuilder,當(dāng)然內(nèi)部還有一些對于低版本兼容的處理優(yōu)化,大家可以閱讀源碼。而后兩個(gè)原理也是一樣的,分別對應(yīng)StateListDrawable和LayerDrawable。
最后再次附上源碼地址SupperShape,大家要是使用過程中有什么不錯(cuò)的建議,歡迎提issue或者評論,順手點(diǎn)個(gè)star那就更好不錯(cuò)了~