Ultra-Pull-To-Refresh动态添加View不能正常显示BUG解决方法

来源:互联网 发布:ios更新系统 数据丢失 编辑:程序博客网 时间:2024/04/27 08:38

    上文讲到Ultra-Pull-To-Refresh框架的简单示例,在动态添加PtrFrameLayout或者PtrClassicFrameLayout时踩到坑了,无法显示添加的子View。代码如下:

  1. PtrFrameLayout ptrLayout = new PtrFrameLayout(this);
  2. ptrLayout.setLayoutParams(new PtrFrameLayout.LayoutParams (PtrFrameLayout.LayoutParams.MATCH_PARENT,PtrFrameLayout.LayoutParams.MATCH_PARENT));
  3. WebVeiw mWeb = new WebView(this);
  4. mWeb.setLayoutParams(new ViewGroup.LayoutParams (ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
  5. ptrLayout.addView(mWeb);

    结果就是提示如下信息

  1. The content view in PtrFrameLayout is empty. Do you forget to specify its id in xml layout file?
    通过查看源码,PtrFrameLayout这个ViewGroup动态添加子View时,还未加进来就调用了onFinishInflate方法,此时获取的子View对象当然为空;所以通过手动调用onFinishInflate()方法来再次获取子View。

    对PtrFrameLayout源码加入以下一段代码:

  1. public void addViewForPtrFrameLayout(View child) {
  2.        super.addView(child);
  3.        if (this.getContentView() == null) {//获取不到子View时再调用一次onFinishInfalte()
  4.            this.onFinishInflate();
  5.        }
  6. }

然后将原来的ptrLayout.addView(mWeb)改用addViewForPtrFrameLayout(mWeb),来动态添加WebView,这样修改并未让WebView正常显示出来,别急还差一步。看下onFinishInflate()源码

  1. protected void onFinishInflate() {
  2.        final int childCount = getChildCount();
  3.        if (childCount > 2) {
  4.            throw new IllegalStateException("PtrFrameLayout only can host 2 elements");
  5.        } else if (childCount == 2) {
  6.            if (mHeaderId != 0 && mHeaderView == null) {
  7.                mHeaderView = findViewById(mHeaderId);
  8.            }
  9.            if (mContainerId != 0 && mContent == null) {
  10.                mContent = findViewById(mContainerId);
  11.            }
  12.            // not specify header or content
  13.            if (mContent == null || mHeaderView == null) {
  14.                View child1 = getChildAt(0);
  15.                View child2 = getChildAt(1);
  16.                if (child1 instanceof WDPtrUIHandler) {
  17.                    mHeaderView = child1;
  18.                    mContent = child2;
  19.                } else if (child2 instanceof WDPtrUIHandler) {
  20.                    mHeaderView = child2;
  21.                    mContent = child1;
  22.                } else {
  23.                    // both are not specified
  24.                    if (mContent == null && mHeaderView == null) {
  25.                        mHeaderView = child1;
  26.                        mContent = child2;
  27.                    }
  28.                    // only one is specified
  29.                    else {
  30.                        if (mHeaderView == null) {
  31.                            mHeaderView = mContent == child1 ? child2 : child1;
  32.                        } else {
  33.                            mContent = mHeaderView == child1 ? child2 : child1;
  34.                        }
  35.                    }
  36.                }
  37.            }
  38.        } else if (childCount == 1) {
  39.            mContent = getChildAt(0);
  40.        } else {
  41.            mIsFinishInflate = true;
  42.            TextView errorView = new TextView(getContext());
  43.            errorView.setClickable(true);
  44.            errorView.setTextColor(0xffff6600);
  45.            errorView.setGravity(Gravity.CENTER);
  46.            errorView.setTextSize(20);
  47.            errorView.setText("The content view in PtrFrameLayout is empty. Do you forget to specify its id in xml layout file?");
  48.            mContent = errorView;
  49.            addView(mContent);
  50.        }
  51.        if (mHeaderView != null) {
  52.            mHeaderView.bringToFront();
  53.        }
  54.        super.onFinishInflate();
  55.    }

    第一次加载失败时,添加了一个errorView的TextView;再次调用onFinishInflate()方法时,此时ViewGroup存在三个子View:TextView、Header、WebView。childCount() > 3,然后就抛异常了。将45-53行部分代码删除或者改为其他非添加子View的处理就OK了。


0 0
原创粉丝点击