1. 程式人生 > >ShapeBuilder-你還在每次寫一個Shape檔案嗎?

ShapeBuilder-你還在每次寫一個Shape檔案嗎?

不知道大家有沒有過這樣的煩惱,開啟Drawable資料夾下到處都是各式各樣的shape定義,其中不乏有一模一樣的樣式,但只是名字不同,或者僅僅只是radius,color不同,但每次一有邊框,圓角,點選效果等都需要定義一個新的shape,今天這個頁面圓角要2dp,明天一樣的又要4dp,或是顏色的變化都需要我們重新寫一個shape.xml,至少我每次寫的時候都有點受不了,為了避免每次這樣做重複的定義,這裡為大家分享一個我用java程式碼來控制shape的生成,動態改變shape的樣式。
效果

原始碼地址

SupperShape

主要特性

  • 不用再寫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那就更好不錯了~