上文講到Ultra-Pull-To-Refresh框架的簡單示例,在動態添加PtrFrameLayout或者PtrClassicFrameLayout時踩到坑了,無法顯示添加的子View。代碼如下:
PtrFrameLayout ptrLayout = new PtrFrameLayout(this);
ptrLayout.setLayoutParams(new PtrFrameLayout.LayoutParams (PtrFrameLayout.LayoutParams.MATCH_PARENT,PtrFrameLayout.LayoutParams.MATCH_PARENT));
WebVeiw mWeb = new WebView(this);
mWeb.setLayoutParams(new ViewGroup.LayoutParams (ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
ptrLayout.addView(mWeb);
結果就是提示如下信息
The content view in PtrFrameLayout is empty. Do you forget to specify its id in xml layout file?
對PtrFrameLayout源碼加入以下一段代碼:
public void addViewForPtrFrameLayout(View child) {
super.addView(child);
if (this.getContentView() == null) {//獲取不到子View時再調用一次onFinishInfalte()
this.onFinishInflate();
}
}
然後將原來的ptrLayout.addView(mWeb)改用addViewForPtrFrameLayout(mWeb),來動態添加WebView,這樣修改並未讓WebView正常顯示出來,別急還差一步。看下onFinishInflate()源碼
protected void onFinishInflate() {
final int childCount = getChildCount();
if (childCount > 2) {
throw new IllegalStateException("PtrFrameLayout only can host 2 elements");
} else if (childCount == 2) {
if (mHeaderId != 0 && mHeaderView == null) {
mHeaderView = findViewById(mHeaderId);
}
if (mContainerId != 0 && mContent == null) {
mContent = findViewById(mContainerId);
}
// not specify header or content
if (mContent == null || mHeaderView == null) {
View child1 = getChildAt(0);
View child2 = getChildAt(1);
if (child1 instanceof WDPtrUIHandler) {
mHeaderView = child1;
mContent = child2;
} else if (child2 instanceof WDPtrUIHandler) {
mHeaderView = child2;
mContent = child1;
} else {
// both are not specified
if (mContent == null && mHeaderView == null) {
mHeaderView = child1;
mContent = child2;
}
// only one is specified
else {
if (mHeaderView == null) {
mHeaderView = mContent == child1 ? child2 : child1;
} else {
mContent = mHeaderView == child1 ? child2 : child1;
}
}
}
}
} else if (childCount == 1) {
mContent = getChildAt(0);
} else {
mIsFinishInflate = true;
TextView errorView = new TextView(getContext());
errorView.setClickable(true);
errorView.setTextColor(0xffff6600);
errorView.setGravity(Gravity.CENTER);
errorView.setTextSize(20);
errorView.setText("The content view in PtrFrameLayout is empty. Do you forget to specify its id in xml layout file?");
mContent = errorView;
addView(mContent);
}
if (mHeaderView != null) {
mHeaderView.bringToFront();
}
super.onFinishInflate();
}
第一次加載失敗時,添加了一個errorView的TextView;再次調用onFinishInflate()方法時,此時ViewGroup存在三個子View:TextView、Header、WebView。childCount() > 3,然後就拋異常了。將45-53行部分代碼刪除或者改爲其他非添加子View的處理就OK了。