無需自定義View,完全解放shape,selector(二)

前言

新年快樂,你們好,我又來了。。。
這篇文章主要是介紹我以前的一個框架BackgroundLibrary預覽功能的實現
相信不少人看過我以前的文章: 無需自定義View,完全解放shape,selector吧 , 經過自定義標籤去設置shape、selector的屬性,省去了一大部分的shape.xml文件。
項目發佈5個月,也累計了1500+的star,如今也基本穩定運行在各個項目中了。java

問題

可是美中不足的是,雖然BackgroundLibrary這個庫解決了繁瑣的xml問題,確始終沒法解決預覽問題(下圖所示),開發者只能直接在app中看到效果,沒法在as中看到效果。這讓咱們開發的時候形成了必定的不便。android


BackgroundLibrary原理是經過給原生控件添加自定義屬性,而後在運行時期生成drawable,這樣產生了shape、selector。而as是不會去編譯代碼的,這就致使了,在沒有編譯的時候編譯器沒法進行預覽。

如何實現預覽

Anko

首先我想到了一個一樣相似原理的框架Anko,經過動態生成佈局來提升app性能,它實現預覽的方式是經過實現一個自定義預覽插件,而後須要預覽的時候,每次build一下項目,而後進行預覽,顯然這種方式和咱們直接運行app沒有太大的區別,並且開發插件的成本較高,不適合採用這種方法。git

Android Studio編譯器

那麼as是如何實現view的預覽的呢?
咱們簡單看一下TextView的源碼:github

TextView有三個構造函數,一般咱們在經過代碼生成佈局的時候只會用到new TextView(context)這樣的方式去生成對象,並且TextView還有兩個構造函數,多了一個參數AttributeSet,而這個參數所包涵的即是咱們在layout.xml中對View設置的各類屬性,as編譯器經過調用這個構造函數,實現了View的預覽。
而這種方法對於這個框架來講是可行的,所以爲了方便你們能夠預覽,我一樣實現了對應的自定義View。

效果及使用方法

效果

使用方法

一、若是須要對View進行預覽,直接把原來的View換成框架內對應的BLView便可,便可展現預覽效果,若是不須要預覽能夠直接忽略這些用於預覽的自定義View;
二、若是沒有效果,make project一下便可;
三、若是BLView中沒有對應的須要預覽的View,能夠很簡單的本身實現一下,以BLTextView爲例:app

public class BLTextView extends AppCompatTextView {
    public BLTextView(Context context) {
        super(context);
    }

    public BLTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public BLTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs){
        BackgroundFactory.setViewBackground(context, attrs, this);
    }
}
複製代碼

繼承所須要預覽的View,而後在構造函數中添加BackgroundFactory.setViewBackground(context, attrs, this)方法便可。
注意
爲了提升性能,這些View在編譯的時候會自動替換爲對應原生的View,因此除了再xml中,不要在代碼中出現任何的BLTextView,不然會報相似以下的錯誤:框架

//錯誤
BLTextView button = findViewById(R.id.text);
//正確
BLTextView button = findViewById(R.id.text);


Caused by: java.lang.ClassCastException: android.support.v7.widget.AppCompatTextView cannot be cast to com.noober.background.view.BLTextView
複製代碼

總結

上面就是我實現思路的一個方式,只需一行代碼setViewBackground去實現自定義View,來進行預覽,而且在運行時替換自定義View,這樣在開發的時候除了須要預覽的狀況,咱們徹底能夠忽略這些自定義控件的存在,這對android sdk的升級改變都不會產生任何影響。歡迎你們提供更多的思路。函數

相關文章
相關標籤/搜索