前言
這是上周遇到的一個(gè)奇怪問(wèn)題荆烈,我在對(duì)UI的時(shí)候發(fā)現(xiàn),我的Toolbar上NavigationIcon和Title之間的距離分得很開(kāi)簸淀,和設(shè)計(jì)稿上的不一樣愚争,因?yàn)榇a是之前的開(kāi)發(fā)人員寫(xiě)的,所以我首先猜想是不是他在中間加了padding或者margin之類(lèi)的屬性访敌,但是找了一圈以后并沒(méi)有發(fā)現(xiàn)任何人工添加的痕跡凉敲,這個(gè)Toolbar是純天然無(wú)污染的,這就讓我很困惑了寺旺,為什么會(huì)出現(xiàn)這種情況呢荡陷?且聽(tīng)我慢慢道來(lái)。
正文
出現(xiàn)上述情況并不是由于代碼的問(wèn)題導(dǎo)致的迅涮,而是因?yàn)镾upport包中出現(xiàn)了新的屬性废赞。我們先來(lái)看一下實(shí)際效果:
圖中可以明顯看出NavigationIcon和Title之間的距離出現(xiàn)了異常,那么解決方案是什么呢叮姑,很簡(jiǎn)單唉地,只需要在Toolbar屬性里加上一行:
app:contentInsetStartWithNavigation="0dp"
那么出現(xiàn)這個(gè)問(wèn)題的原因在哪呢,我們還是去代碼中找答案传透,這是從Toolbar的onLayout()方法中整理出的代碼:
final int contentInsetLeft = getCurrentContentInsetLeft();
left = Math.max(left, contentInsetLeft);
int titleLeft = left;
mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom);
可以看到這個(gè)left就是TitleTextView在layout時(shí)的left耘沼,并且left是在自身和contentInsetLeft中取較大值得出的,left本身的值就是NavigationIcon的寬度朱盐,一般情況下為56dp群嗤,那么我們的重心就放在了getCurrentContentInsetLeft()方法上,我們來(lái)看一下getCurrentContentInsetLeft()的代碼:
public int getCurrentContentInsetLeft() {
return ViewCompat.getLayoutDirection(this) == ViewCompat.LAYOUT_DIRECTION_RTL
? getCurrentContentInsetEnd()
: getCurrentContentInsetStart();
}
由于我們的Toolbar是從左到右顯示的兵琳,所以我們接著看getCurrentContentInsetStart()方法:
public int getCurrentContentInsetStart() {
return getNavigationIcon() != null
? Math.max(getContentInsetStart(), Math.max(mContentInsetStartWithNavigation, 0))
: getContentInsetStart();
}
這個(gè)方法其實(shí)是在比較getContentInsetStart()和mContentInsetStartWithNavigation并且返回較大值狂秘,這兩個(gè)值我們可以在style文件中找到:
<style name="Base.Widget.AppCompat.Toolbar" parent="android:Widget">
<item name="contentInsetStart">16dp</item>
<item name="contentInsetStartWithNavigation">@dimen/abc_action_bar_content_inset_with_nav</item>
</style>
<dimen name="abc_action_bar_content_inset_with_nav">72dp</dimen>
綜合以上我們可以知道,getCurrentContentInsetLeft()方法最終得到的值是72dp躯肌,這個(gè)值再和前面提到的left自身的值56dp相比取較大值者春,就得到了72dp。這就是間距異常的原因清女!所以我們只需要將contentInsetStartWithNavigation屬性設(shè)為0dp就可以恢復(fù)到正常間距钱烟。
但是為什么會(huì)出現(xiàn)這個(gè)contentInsetStartWithNavigation屬性呢,在網(wǎng)上查找資料后得出的結(jié)論是:contentInsetStartWithNavigation這個(gè)屬性是Support包在V22之后的版本才加上的嫡丙,而V22的Toolbar代碼中只會(huì)根據(jù)contentInsetStart來(lái)計(jì)算Title的左邊距拴袭。
好了,到這里就真相大白了曙博,再遇到這種情況我們只需要簡(jiǎn)單的加上一行代碼就可以輕松解決拥刻,并且有理有據(jù),豈不美滋滋羊瘩。
結(jié)語(yǔ)
果然泰佳,代碼是不會(huì)騙人的盼砍,一切都可以從代碼里找到答案尘吗。今天就寫(xiě)到這逝她,該洗洗睡覺(jué)了。如有錯(cuò)誤睬捶,歡迎大家指正黔宛。