前言
新年快樂,大家好,我又來了。。。
這篇文章主要是介紹我之前的一個框架BackgroundLibrary,預覽功能的實現。
相信很多人看過我之前的文章:
無需自定義View,徹底解放shape,selector吧 ,
通過自定義標籤去設定shape、selector的屬性,省去了一大部分的shape.xml檔案。
專案釋出5個月,也累計了1500+的star,現在也基本穩定執行在各個專案中了。
問題
但是美中不足的是,雖然BackgroundLibrary這個庫解決了繁瑣的xml問題,確始終無法解決預覽問題(下圖所示),開發者只能直接在app中看到效果,無法在as中看到效果。這讓我們開發的時候造成了一定的不便。
BackgroundLibrary原理是通過給原生控制元件新增自定義屬性,然後在執行時期生成drawable,這樣產生了shape、selector。而as是不會去編譯程式碼的,這就導致了,在沒有編譯的時候編譯器無法進行預覽。
如何實現預覽
Anko
首先我想到了一個同樣類似原理的框架Anko,通過動態生成佈局來提高app效能,它實現預覽的方式是通過實現一個自定義預覽外掛,然後需要預覽的時候,每次build一下專案,然後進行預覽,顯然這種方式和我們直接執行app沒有太大的區別,而且開發外掛的成本較高,不適合採用這種方法。
Android Studio編譯器
那麼as是如何實現view的預覽的呢?
我們簡單看一下TextView的原始碼:
而這種方法對於這個框架來說是可行的,因此為了方便大家可以預覽,我同樣實現了對應的自定義View。
效果及使用方法
效果
使用方法
1、如果需要對View進行預覽,直接把原來的View換成框架內對應的BLView即可,即可展示預覽效果,如果不需要預覽可以直接忽略這些用於預覽的自定義View;
2、如果沒有效果,make project一下即可;
3、如果BLView中沒有對應的需要預覽的View,可以很簡單的自己實現一下,以BLTextView為例:
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的升級改變都不會產生任何影響。歡迎大家提供更多的思路。