上文讲到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了。