ShapeBuilder-你還在每次寫一個Shape檔案嗎?
不知道大家有沒有過這樣的煩惱,開啟Drawable資料夾下到處都是各式各樣的shape定義,其中不乏有一模一樣的樣式,但只是名字不同,或者僅僅只是radius,color不同,但每次一有邊框,圓角,點選效果等都需要定義一個新的shape,今天這個頁面圓角要2dp,明天一樣的又要4dp,或是顏色的變化都需要我們重新寫一個shape.xml,至少我每次寫的時候都有點受不了,為了避免每次這樣做重複的定義,這裡為大家分享一個我用java程式碼來控制shape的生成,動態改變shape的樣式。
原始碼地址
主要特性
- 不用再寫shape.xml檔案了!!!
- 鏈式呼叫
- 涵蓋Shape幾乎常用的所有屬性,如:TYPE,Radius,Stroke,Soild,Gradient,GradientType,GradientCenter,GradientRadius,Size
- 支援Selector
- 支援Layer-list
如何使用
1.ShapeBuilder
非常簡單,來看看最基本的使用方式,比如一個帶邊框的View。
ShapeBuilder.create()
.Type(RECTANGLE)
.Soild(Color.RED)
.Stroke (5,Color.BLACK)
.build(View);
設定對應的屬性,呼叫build(View)傳入需要設定背景的view即可。如果需要獲得構建的drawable可以呼叫該build()方法返回。
利用Builder模式,實現了一系列的鏈式呼叫,方便我們設定屬性值。
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
其實這個是基於ShapeBuilder,將幾個主要的都順便封裝了一下,可以替代Selector的定義。
ShapeListBuilder.create(Drawable drawable)//傳預設狀態下的drawable
.addShape(Drawable shape, int... state)//狀態對應的drawable和state
.build(View view);
3.LayerBuilder替代Layer-list
用於替代Layer
LayerBuilder.create(Drawable... drawables)
.Bottom(1, 15)//top,right...setInset等
.build(View view);
用法其實都比較簡單無腦,記住要最後呼叫build(View view)方法~
原理
原理其實也比較基礎,我們每次定義Shape檔案,其實最後會被生成GradientDrawable,通過檢視GradientDrawable原始碼,我們其實能看到我們定義的type,Radius,solid等屬性其實就是最後在這裡面通過TypeArray讀取出來,最後生成了GradientDrawable物件,所以我們只是需要對GradientDrawable原始碼進行閱讀理解,考慮到GradientDrawable屬性眾多這一特點,利用Build模式進行封裝,便實現了ShapeBuilder,當然內部還有一些對於低版本相容的處理優化,大家可以閱讀原始碼。而後兩個原理也是一樣的,分別對應StateListDrawable和LayerDrawable。
最後再次附上原始碼地址SupperShape,大家要是使用過程中有什麼不錯的建議,歡迎提issue或者評論,順手點個star那就更好不錯了~