1. 程式人生 > >Android @BindView時報Required view ID was not found 異常

Android @BindView時報Required view ID was not found 異常

最近,在做公司客製化專案的時候遇到一個問題:有些layout下面的xml佈局檔案需要進行動態的載入,而我使用的是ButterKnife去繫結的view,而且在類的全域性變數中已經宣告好了,如下所示:

@BindView(R.id.ll_display_a)
LinearLayout llDisplayA;
@BindView(R.id.ll_display_b)
LinearLayout llDisplayB;
上面兩個佈局在不同的場景下載入,因此對應的layout佈局也不同(llDisplayA對應的是佈局layout_a.xml,llDisplayB對應的是佈局layout_b.xml),而Butterknife並沒有這麼智慧,只要是需要載入的view,都可以通過@BindView的註解形式進行初始化,點選事件也可通過 layout_a.xml,而Butterknife並沒有這麼智慧,只要是需要載入的view,都可以通過@BindView的註解形式進行初始化,以及點選事件通過@onViewCliked的形式指定。那麼問題來了,如果我只初始化了layout_a.xml,
而變數
llDisplayB在類中已經宣告,執行程式之後會報錯,報錯如下:
12-13 11:55:56.187  4158  4158 E AndroidRuntime: java.lang.IllegalStateException: Required view 'll_display_b' with ID 2131558712 for method 'onViewClicked' was not found. If this view is optional add '@Nullable' (fields) or '@Optional' (methods) annotation.
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at butterknife.internal.Utils.findRequiredView(Utils.java:92)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at com.xbh.systemsetting.advancedsetting.view.AdvancedFragment_ViewBinding.<init>(AdvancedFragment_ViewBinding.java:322)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at java.lang.reflect.Constructor.newInstance(Native Method)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at butterknife.ButterKnife.createBinding(ButterKnife.java:199)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at butterknife.ButterKnife.bind(ButterKnife.java:172)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at com.xbh.systemsetting.advancedsetting.view.AdvancedFragment.initView(AdvancedFragment.java:765)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at com.xbh.systemsetting.advancedsetting.view.AdvancedFragment.onCreateView(AdvancedFragment.java:299)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.app.FragmentManagerImpl.execSingleAction(FragmentManager.java:1984)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:626)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:143)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.view.ViewPager.populate(ViewPager.java:1268)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.view.ViewPager.populate(ViewPager.java:1116)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1642)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.view.View.measure(View.java:18788)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.view.View.measure(View.java:18788)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1112)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.widget.LinearLayout.onMeasure(LinearLayout.java:632)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.view.View.measure(View.java:18788)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1112)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.widget.LinearLayout.onMeasure(LinearLayout.java:632)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.view.View.measure(View.java:18788)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.view.View.measure(View.java:18788)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.widget.LinearLayout.measureVertical(LinearLayout.java:748)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.widget.LinearLayout.onMeasure(LinearLayout.java:630)
12-13 11:55:56.187  4158  4158 E AndroidRuntime: 	at android.view.View.measure(View.java:1[  179.092576] init: Service 'cpudvfsscaling' is being killed...
8788)

檢視列印資訊,發現Required view ID was not found ,說有一個id為ll_display_b的view未找到。緊接著,我注意到了後面一句話:

If this view is optional add '@Nullable' (fields) or '@Optional' (methods) annotation.
它說如果這個view是可選的,那麼可以加上@Nullable(變數)或者@Optional(方法)註解。這時我才發現這才是解決問題的關鍵所在,而且ButterKnife也確實考慮到了這一點。於是我在成員變數的@BindView註解上面加上了@Nullable,在點選事件@onViewCliked上加上了@Optional註解:
//必須加上@Nullable註解,這樣即使控制元件id不存在,也不會報空指標異常
@Nullable
@BindView(R.id.ll_display)
LinearLayout llDisplay;
//必須加上@Optional註解,這樣即使控制元件id不存在,也不會報空指標異常
@Optional
@OnClick({R.id.ll_display_b})
public void onViewClicked(View view) {}
問題完美解決!