带有PageTransformer的嵌套片段中带有ViewPager的dispatchDraw上的Nullpointerexception

时间:2014-04-13 01:34:21

标签: java android android-fragments android-viewpager

我在Android应用中遇到了一个非常不明显的错误。我有一个片段,它依次包含一个由FragmentStatePagerAdapter支持的ViewPager。寻呼机包含两个片段。

每当我尝试添加一个PageTransformer(使用Android开发者网站上的那些:http://developer.android.com/training/animation/screen-slide.html)时,一切正常,直到我尝试离开包含viewpager(backpress或regular)的片段。我得到的错误如下。我无法真正追踪导致它的原因x_x。底部的传呼机构造的代码片段。

Process: edu.utcs.android, PID: 11728
    java.lang.NullPointerException
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2946)
            at android.view.View.draw(View.java:14476)
            at android.support.v4.view.ViewPager.draw(ViewPager.java:2171)
            at android.view.View.getDisplayList(View.java:13370)
            at android.view.View.getDisplayList(View.java:13412)
            at android.view.View.draw(View.java:14190)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
            at android.view.View.draw(View.java:14476)
            at android.widget.FrameLayout.draw(FrameLayout.java:472)
            at android.view.View.getDisplayList(View.java:13370)
            at android.view.View.getDisplayList(View.java:13412)
            at android.view.View.draw(View.java:14190)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
            at android.view.View.getDisplayList(View.java:13365)
            at android.view.View.getDisplayList(View.java:13412)
            at android.view.View.draw(View.java:14190)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2959)
            at android.view.View.getDisplayList(View.java:13365)
            at android.view.View.getDisplayList(View.java:13412)
            at android.view.View.draw(View.java:14190)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
            at android.support.v4.widget.DrawerLayout.drawChild(DrawerLayout.java:870)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
            at android.view.View.getDisplayList(View.java:13365)
            at android.view.View.getDisplayList(View.java:13412)
            at android.view.View.draw(View.java:14190)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
            at android.view.View.getDisplayList(View.java:13365)
            at android.view.View.getDisplayList(View.java:13412)
            at android.view.View.draw(View.java:14190)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
            at android.view.View.draw(View.java:14476)
            at com.android.internal.widget.ActionBarOverlayLayout.draw(ActionBarOverlayLayout.java:381)
            at android.view.View.getDisplayList(View.java:13370)
            at android.view.View.getDisplayList(View.java:13412)
            at android.view.View.draw(View.java:14190)
            at android.view.ViewGroup.drawChild(ViewGroup.java:3103)
            at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2940)
            at android.view.View.draw(View.java:14476)
            at android.widget.FrameLayout.draw(FrameLayout.java:472)
            at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2324)
            at android.view.View.getDisplayList(View.java:13370)
            at android.view.View.getDisplayList(View.java:13412)
            at android.view.HardwareRenderer$GlRenderer.buildDisplayList(HardwareRenderer.java:1577)
            at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1449)
            at android.view.ViewRootImpl.draw(ViewRootImpl.java:2410)
            at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2282)
            at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1912)
            at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1022)
            at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5708)
            at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
            at android.view.Choreographer.doCallbacks(Choreographer.java:562)
            at android.view.Choreographer.doFrame(Choreographer.java:532)
            at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
            at android.os.Handler.handleCallback(Handler.java:733)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5083)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:777)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:593)
            at de.robv.andro

寻呼机构建:

mAdapter = new LabPagerAdapter(getChildFragmentManager());
        mPager.setAdapter(mAdapter);
        mPager.setPageTransformer(false, new ZoomOutPageTransformer());
        mPager.setCurrentItem(mLabPosition);

我尝试重新安排一些线路,以防它出现某种竞争条件,并尝试倒转动画(&#34; false&#34;布线在第3行),但没有运气。< / p>

修改

通过一些试验和错误,以及来自user2152081的一些帮助,我已经通过使用我自己的方法覆盖ViewPager类,并在try / catch块中的draw()中包装超级调用来进行hacky解决方法。

@Override
public void draw(Canvas canvas) {
    try {
        super.draw(canvas);
    } catch (NullPointerException e) {
        Log.d("ViewPager", "Nullpointer skipped");
    }
}

1 个答案:

答案 0 :(得分:6)

我没有足够的代表发表评论,所以我会在这里回答。

我遇到了完全相同的问题。查看ViewGroup的源代码,它正在运行 android.support.v4.view.ViewPager 的子代,并在那里点击NPE。如你所述,删除页面转换器工作,就像删除PagerTabStrip一样。我现在正在看它,但它看起来像页面转换器和PagerTabStrip之间的某种不兼容。

具体来说,当要求ViewPager重绘自己时,在堆栈跟踪的顶部:

at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2946)
at android.view.View.draw(View.java:14476)
at android.support.v4.view.ViewPager.draw(ViewPager.java:2171)

对我来说,此时ViewPager只有一个孩子 - PagerTabStrip。在ViewGroup的dispatchDraw中,这是NPE弹出的地方:

for (int i = 0; i < count; i++) {
    final View child = children[getChildDrawingOrder(count, i)];
    if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
        more |= drawChild(canvas, child, drawingTime);
    }
}

其中children []包含PagerTabStrip作为它的第0个条目,由于某种原因,子[getChildDrawingOrder(count,i)]正在评估为null。

getchildDrawingOrder(count, i) 

在我的实现中没有重载,所以它只返回i。它超出了我为什么评估为null - 它看起来肯定应该返回PagerTabStrip,但它不是,它在尝试访问孩子时会产生NPE [0]&#39 ;成员。

我没有解决方案,但希望这与您遇到的情况类似。如果你发现任何事情,请告诉我。

修改

不太清楚为什么,但用这个替换我的ViewPager似乎解决了崩溃问题:

package ca.test;

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;

public class TestViewPager extends ViewPager {

    public TestViewPager(Context context) {
        super(context);
    }

    public TestViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected int getChildDrawingOrder(int childCount, int i) {
        return i;
    }

}