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

Zac*_*ers 6 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
Run Code Online (Sandbox Code Playgroud)

寻呼机结构:

mAdapter = new LabPagerAdapter(getChildFragmentManager());
        mPager.setAdapter(mAdapter);
        mPager.setPageTransformer(false, new ZoomOutPageTransformer());
        mPager.setCurrentItem(mLabPosition);
Run Code Online (Sandbox Code Playgroud)

我已经尝试重新排列一些行,以防它出现某种竞争条件,并尝试反转动画(第3行的"假"布尔值),但没有运气.

编辑

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

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

use*_*081 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)
Run Code Online (Sandbox Code Playgroud)

对我来说,此时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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

getchildDrawingOrder(count, i) 
Run Code Online (Sandbox Code Playgroud)

在我的实现中没有重载,所以它只返回i.它超出了我为什么评估为null - 它似乎应该返回PagerTabStrip,但它不是,并且它在尝试访问孩子[0]的成员时产生NPE.

我没有你的解决方案,但希望这与你遇到的情况类似.如果你发现什么,请告诉我.

编辑

不太清楚为什么,但用这个替换我的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;
    }

}
Run Code Online (Sandbox Code Playgroud)