toolbar中設定左上角按鈕及其點擊事件的順序的原因


這兩天研究toolbar,網上找了些帖子,看完后對於toolbar設定的一些順序不太清楚,比如設置setNavigationIcon,setNavigationOnClickListener必須在setSupportActionBar后面,原文關於這方面用“為什么在setSupportActionBar(toolbar);后面加入而不在前面,你可以加入到前面試試,雖然可以顯示回退的圖片,但是點擊並沒有調用該按鈕的點擊事件,而在setSupportActionBar(toolbar);后面設置點擊才有反應。一定要記住,不然回退是不會起作用的。”但是沒說為什么,讓我感覺極其不爽,所以覺得需要找到真正原因,下面記錄尋找過程:

 

經過嘗試,發現setNavigationIcon可以在setSupportActionBar前面,如圖1,

但是如果setNavigationOnClickListener在setSupportActionBar前面則點擊事件沒有反應,與原文中的表述一致,那么來查下原因,我先設想了下,什么情況下會出現這種情況,考慮再三,只想到了一種情況,就是在setSupportActionBar的時候系統重新設置了點擊事件,把之前我設置的點擊事件頂掉了,猜到可能的原因后就是驗證的過程。

 

首先查看setSupportActionBar的源碼,它是AppCompatActivity中的方法:

getDelegate()返回了一個AppCompatDelegate,再進去看下AppCompatDelegate的setSupportActionBar:

發現是個抽象的方法,那么就看一下getDelegate()是返回的AppCompatDelegate的哪個子類吧,看下getDelegate()方法:

沒什么說得,看下create()方法:

這里看到根據版本的不同,會有三個子類,我們分別進去看看:

已經很明顯的看清了繼承關系,現在開始從AppCompatDelegateImplV14向AppCompatDelegateImplBase逐個類查找setSupportActionBar方法,結果發現AppCompatDelegateImplV14、AppCompatDelegateImplV11中都沒有setSupportActionBar方法,該方法只存在於AppCompatDelegateImplV7中:

看到上圖中紅框部分,將toolbar當作構造參數傳入了對象ToolbarActionBar,看下ToolbarActionBar中是怎么使用toolbar的:

看到上圖中紅框部分,將toolbar當作構造參數傳入了對象ToolbarWidgetWrapper,只能繼續看下ToolbarWidgetWrapper中是怎么使用toolbar的:

在ToolbarWidgetWrapper將toolbar緩存給了mToolbar,那么繼續向下找mToolbar在此類中的使用情況:

到這里已經完全清楚了,在ToolbarWidgetWrapper的構造方法里,new了新的OnClickListener傳進去,這里驗證了我前面猜測的正確性,也就是setNavigationOnClickListener在setSupportActionBar前面設置則點擊事件沒有反應的原因是因為在setSupportActionBar的時候系統重新設置了點擊事件,把之前設置的點擊事件頂掉了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM