為Fragment也寫一個ViewInject


title: 為Fragment也寫一個ViewInject
date: 2018-10-28 11:29:51
tags: fragment ViewInject


1.簡介

鴻洋博客:https://blog.csdn.net/lmj623565791/article/details/39269193
前段時間根據(jù)鴻洋的博客,寫了一個ViewInject,本以為可以和findViewById說再見了,但是今天在fragment中使用ViewInject,卻報了空指針的錯誤,原來是控件沒有實例化就調(diào)用了。找了一下,我把目光放到ViewInjectUtil.inject(getActivity)上。

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        ViewInjectUtils.inject(getActivity());//問題可能出在這里
        init();
        setListener();
    }

ViewInject只是一個標(biāo)志,實際上是通過inject方法調(diào)用其他方法,讀取ViewInect中的值,實現(xiàn)動態(tài)綁定。因為Activity中可以直接調(diào)用findViewById()方法,而Fragment中則需要先獲得所綁定的視圖View,然后通過view.findViewById()來獲取控件。
所以有必要給fragment重新寫一個inject()方法,網(wǎng)上沒有太多關(guān)于Fragment的inject(),干脆自己動手寫一個,以下代碼基于鴻洋博客中代碼加以修改。

2.動手為Fragment寫一個inject()方法

在ViewInjectUtils.java中添加方法fragmentInject()

public static void fragmentInject(Fragment fragment){
    fragmentInjectViews(fragment);
}

因為是給Fragment用的,所以傳入的參數(shù)是一個Fragment,不再是activity。fragmentInjectView()是具體的注入方法,接下來我們來寫fragmentInjectView()

private static void fragmentInjectViews(Fragment fragment){
        Class<? extends View> viewClass = fragment.getView().getClass();
        Class<? extends Fragment> fragmentClass = fragment.getClass();
        Field[] fields = fragmentClass.getDeclaredFields();
        //遍歷所有成員對象
        for(Field field : fields){
            ViewInject viewInjectAnnotation = field.getAnnotation(ViewInject.class);
            if (viewInjectAnnotation != null) {
                int viewId = viewInjectAnnotation.value();
                if(viewId != -1){
                    Log.e("TAG", "injectViews: "+viewId);
                    //初始化View
                    try {
                        //通過view獲取fingViewById()方法
                        Method method = viewClass.getMethod(METHOD_FIND_VIEW_BY_ID, int.class);
                        //讓view調(diào)用findViewById()獲取到控件對象,返回獲取到控件對象的fragmentlayout
                        Object resView = method.invoke(fragment.getView(), viewId);
                        field.setAccessible(true);
                        //將fragmentLayout設(shè)置給fragment.
                        field.set(fragment, resView);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

不同的地方有3處:

  1. 聲明了viewClass和fragmentClass兩個變量。viewClass是fragment所綁定view的反射類,fragmentClass就是我們寫的Fragment類的反射類。
  2. fields是通過fragmentClass獲取的Fragment類中的字段
  3. 在"初始化View"下面,Method是通過viewClass獲得的,resView也是通過fragment.getView()來取得對應(yīng)ID的view。

主要思路:控件的引用聲明在fragment中,但要通過view的findViewById方法獲取控件對象,所以我們既需要fragment,又需要其對應(yīng)的View。第2處不同中,獲取到了fragment中聲明的字段(其中包括我們聲明的控件引用),第3處不同中,我們通過view獲取到findViewById()方法,之后通過讓view執(zhí)行findViewById()方法獲取到對應(yīng)的控件對象,返回的resView是一個獲取到控件對象的fragmentLayout,最后把它set給我們的fragment。

3.在fragment中調(diào)用fragmentInject()方法

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        ViewInjectUtils.fragmentInject(this);
        init();
        setListener();
    }

我們在onActivityCreated中調(diào)用fragmentInject()方法,因為fragmrent在onCreateView()中已經(jīng)綁定了所屬的view,之后通過getView()方法取得view。

4.總結(jié)

這里用到的是java反射的知識,感覺自己對這一塊還很陌生,正好借這個機(jī)會稍微了解了一下這方面的知識,寫下記錄希望對大家有用。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,828評論 25 709
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 13,929評論 2 59
  • 一 Activity 1 Activity 生命周期 1.1 Activity 的四種狀態(tài) running 當(dāng)前...
    _執(zhí)_念__閱讀 10,772評論 0 91
  • 游戲的開始,或許愛,真的存在。 你不知道為什么為我著迷, 我不知道為什么對你崇拜, 就這樣的開始掉入我們的漩渦,無...
    cf5714e8e8b6閱讀 252評論 0 0
  • 秋高氣爽、五谷飄香、碩果累累,進(jìn)入秋季氣溫也由熱轉(zhuǎn)涼,人體消耗也隨之逐漸減少。暑濕乏困也...
    悠然bxy閱讀 549評論 0 0

友情鏈接更多精彩內(nèi)容