今天使用spinner時(shí)引發(fā)了一個(gè)崩潰大坑怨喘,debug了一會(huì)依然不知所以谢揪,翻看了源碼才發(fā)現(xiàn)癥結(jié)所在懦傍。故此記錄一下鱼蝉。
spinner設(shè)置了spinnerMode為dropdown(默認(rèn)也是dropdown),此時(shí)假如是自定義adapter院尔,需要特別注意adapter的實(shí)現(xiàn)方式蜻展。
因adapter需要實(shí)現(xiàn)SpinnerAdapter接口,這里有兩個(gè)方法getDropDownView和getView邀摆,關(guān)于這兩個(gè)的區(qū)別網(wǎng)上一般認(rèn)為getView 設(shè)置的是Spinner下拉打開(kāi)前的布局纵顾,getDropDownView 設(shè)置的是下拉打開(kāi)后,下拉的布局栋盹。這個(gè)說(shuō)法含糊不清施逾,實(shí)際上看源碼可知這兩個(gè)是有關(guān)聯(lián)的。
AppCompatSpinner源碼片段:
@Override
public void setAdapter(SpinnerAdapter adapter) {
// The super constructor may call setAdapter before we're prepared.
// Postpone doing anything until we've finished construction.
if (!mPopupSet) {
mTempAdapter = adapter;
return;
}
super.setAdapter(adapter);
if (mPopup != null) {
final Context popupContext = mPopupContext == null ? getContext() : mPopupContext;
mPopup.setAdapter(new DropDownAdapter(adapter, popupContext.getTheme()));
}
}
可以看出當(dāng)mPopup!=null時(shí)汉额,設(shè)置的adapter為DropDownAdapter曹仗,跟蹤DropDownAdapter看下:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return getDropDownView(position, convertView, parent);
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
return (mAdapter == null) ? null
: mAdapter.getDropDownView(position, convertView, parent);
}
可以看到getView方法最終還是調(diào)用了getDropDownView方法。因此如果spinner的spinnerMode為dropdown蠕搜,在自定義adapter時(shí)一定要記得重寫(xiě)getDropDownView方法怎茫,否則getView就會(huì)取到null值,從而引發(fā)閃退血案妓灌。