LayoutInflater.SetFactory()學(xué)習(xí)(2)

參考1
參考2
完整github代碼

一:LayoutInflaterFactory的用途:

自行創(chuàng)建自定義的View,而不是讓系統(tǒng)去創(chuàng)建脊岳,可以避免系統(tǒng)的反射過程逝段,提升性能;
在XML使用自定義View的時候垛玻,可以不聲明全限定名稱;
更換系統(tǒng)View為自己定義View奶躯,這正是Appcompat庫替換默認(rèn)的系統(tǒng)View的方式帚桩。

二:使用LayoutInflaterFactory的方式

(1)自定義LayoutInflaterFactory

通過繼承Support Library的LayoutInflaterFactory,在Activity里面設(shè)置自定義的LayoutInflaterFactory

@Override public void onCreate(Bundle savedInstanceState) {
    LayoutInflaterCompat.setFactory(getLayoutInflater(), new MyLayoutInflaterFactory(this));
    super.onCreate(savedInstanceState);
    ...
}

注意:super.onCreate(savedInstanceState);之前設(shè)置自定義LayoutInflaterFactory嘹黔;否則自定義的LayoutInflaterFactory不會生效账嚎。
LayoutInflater factories的最大限制是一個factory只能綁定一個LayoutInflater,因?yàn)閟upport library已經(jīng)綁定自己的factory儡蔓;設(shè)置自定義的LayoutInflaterFactory可能會帶來一些問題郭蕉,比如無法從XML文件中加載Fragment,無法加載v21包里面的屬性;

官方文檔:
如果使用自定義的Factory浙值,可以忽略調(diào)用 installViewFactory 方法恳不,然后直接調(diào)用 createView() 方法 返回兼容的View;

document

也就是說自定義LayoutInflaterFactory負(fù)責(zé)調(diào)用

AppCompatDelegate#createView(android.view.View, String, android.content.Context, android.util.AttributeSet

下面這個方法可以克服一個LayoutInflater只能設(shè)置一個LayoutInflaterFactory的缺陷;它會創(chuàng)建一個新的LayoutInflater實(shí)例开呐,然后綁定你可以給它綁定自定義的Factory烟勋;它是通過合并自定義factory和support library的 factory 來實(shí)現(xiàn)的;如果調(diào)用這個方法來創(chuàng)建LayoutInflater實(shí)例筐付,需要在Activity中重寫getLayoutInflater()getSystemService(String)來返回自己的LayoutInflater

LayoutInflater#cloneInContext(Context)
(2)使用Activity作為LayoutInflaterFactory

所有的LayoutInflater都設(shè)置了一個默認(rèn)的LayoutInflaterFactory卵惦,Activity默認(rèn)實(shí)現(xiàn)了Factory和Factory2;
這樣在Activity中就允許 override下面的兩個方法來處理自定義view的加載瓦戚。

View onCreateView(View, String, Context, AttributeSet);
View onCreateView(String, Context, AttributeSet);

三:LayoutInflater Factory創(chuàng)建方法

(1)一個在XML文件中的移除自定義View全限定名稱的 Factory

移除自定義View全限定名稱的好處:(1)如果自定義View被重構(gòu)(refactor)了沮尿,不用在XML文件中修改肢扯;(2)增強(qiáng)可讀性
一個Factory的例子

public class MyLayoutInflaterFactory implements LayoutInflaterFactory {
    @Override
    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
        if (TextUtils.equals(name, "DebugDrawerLayout")) {
            return new DebugDrawerLayout(context, attrs);
        } else if (TextUtils.equals(name, "ScrimInsetsFrameLayout") {
            return new ScrimInsetsFrameLayout(context, attrs);
        }
        // and so on...
    }
}

上面代碼的問題: 如果按照上面的寫法可能要列出所有的自定義View,然后一個個判斷姿搜;
改進(jìn)為使用反射的方式創(chuàng)建;

public class MyLayoutInflaterFactory implements LayoutInflaterFactory {
    private static final String CUSTOM_VIEWS_PACKAGE = "com.example.ui.customviews.";

    private static final Class<?>[] constructorSignature = new Class[] { 
            Context.class, AttributeSet.class };

    @Override
    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
        Constructor<? extends View> constructor = null;
         //通過classLoader來加載類(全限定名稱)呀洲;
        Class<? extends View> clazz = context.getClassLoader()
                .loadClass(CUSTOM_VIEWS_PACKAGE + name).asSubclass(View.class);
          //獲取構(gòu)造函數(shù)
        constructor = clazz.getConstructor(constructorSignature);
        constructor.setAccessible(true);
        return constructor.newInstance(context, attrs);
    }
}

上面代碼的缺陷是沒有反射cache;

四:如何在自定義LayoutInflaterFactory中保留support library的特性印衔;

public class CustomViewsLayoutInflaterFactory implements LayoutInflaterFactory {
    private AppCompatDelegate appCompatDelegate;

    public CustomViewsLayoutInflaterFactory(AppCompatDelegate appCompatDelegate) {
        this.appCompatDelegate = appCompatDelegate;
    }

    @Override
    public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
        View result = null;

        // todo: your custom inflation code here!

        if (result == null) {
            // Get themed views from AppCompat
            result = appCompatDelegate.createView(parent, name, context, attrs);
        }
        return result;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末啡捶,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子奸焙,更是在濱河造成了極大的恐慌瞎暑,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件与帆,死亡現(xiàn)場離奇詭異了赌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)玄糟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門勿她,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人阵翎,你說我怎么就攤上這事嫂拴〔ゾ荆” “怎么了贮喧?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵筒狠,是天一觀的道長。 經(jīng)常有香客問我箱沦,道長辩恼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任谓形,我火速辦了婚禮灶伊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寒跳。我一直安慰自己聘萨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布童太。 她就那樣靜靜地躺著米辐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪书释。 梳的紋絲不亂的頭發(fā)上翘贮,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機(jī)與錄音爆惧,去河邊找鬼狸页。 笑死,一個胖子當(dāng)著我的面吹牛扯再,可吹牛的內(nèi)容都是我干的芍耘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼熄阻,長吁一口氣:“原來是場噩夢啊……” “哼斋竞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起饺律,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤窃页,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后复濒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脖卖,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年巧颈,在試婚紗的時候發(fā)現(xiàn)自己被綠了畦木。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡砸泛,死狀恐怖十籍,靈堂內(nèi)的尸體忽然破棺而出蛆封,到底是詐尸還是另有隱情,我是刑警寧澤勾栗,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布惨篱,位于F島的核電站,受9級特大地震影響围俘,放射性物質(zhì)發(fā)生泄漏砸讳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一界牡、第九天 我趴在偏房一處隱蔽的房頂上張望簿寂。 院中可真熱鬧,春花似錦宿亡、人聲如沸常遂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽克胳。三九已至,卻和暖如春坤按,著一層夾襖步出監(jiān)牢的瞬間毯欣,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工臭脓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留酗钞,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓来累,卻偏偏與公主長得像砚作,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子嘹锁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,111評論 25 707
  • afinalAfinal是一個android的ioc葫录,orm框架 https://github.com/yangf...
    passiontim閱讀 15,429評論 2 45
  • DataBinding 庫是 Google 公司 Android Framework UI 工具團(tuán)隊(duì)開發(fā)出來的一款...
    bravian閱讀 5,420評論 2 16
  • 其實(shí),很早就想寫一篇舞蹈的文章了领猾。 當(dāng)然最近跟我聊舞的人也蠻多的米同。 因?yàn)槲抑溃芏嗯⒁捕几乙粯铀じ停恢庇幸粋€“...
    梓涼閱讀 1,255評論 2 0
  • 之七 汕大圖書館面粮,此行一重點(diǎn), 外觀并無奇继低,方形很平淡熬苍。 內(nèi)部有洞天,設(shè)計(jì)實(shí)堪贊: 中庭為天井,回字形擴(kuò)展柴底, 四條...
    沁園春M閱讀 171評論 2 3