Why am I getting a null reference on my RecyclerView

后端 未结 5 747
攒了一身酷
攒了一身酷 2021-02-02 12:37

I am trying to use the RecyclerView in my fragments. It shows up fine for the first tab, but when I swipe to the second tab and then back to the first one I get the following er

5条回答
  •  别那么骄傲
    2021-02-02 13:20

    Basically, the LayoutManager is being disposed of before your recycler has finished with it.

    From the Android source :

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mItemAnimator != null) {
            mItemAnimator.endAnimations();
        }
        mFirstLayoutComplete = false;
        stopScroll();
        mIsAttached = false;
        if (mLayout != null) {
            mLayout.onDetachedFromWindow(this, mRecycler);
        }
        removeCallbacks(mItemAnimatorRunner);
    }
    

    The problem stems from when the stopScroll and it tries to call mLayout.stopSmoothScroller(); without checking if mLayout is null.

    I threw togeather a very hacky hot fix for an app I've been working on, but I wouldn't suggest using this for a long term solution as it's very much a bodge. If like me you have a tight deadline it's best to just catch the null pointer exception and ignore it.

    My hot fix was just to create a custom View extending the RecyclerView :

    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.util.AttributeSet;
    
    public class HotFixRecyclerView extends RecyclerView
    {
        public HotFixRecyclerView( Context context )
        {
            super( context );
        }
    
        public HotFixRecyclerView( Context context, AttributeSet attrs )
        {
            super( context, attrs );
        }
    
        public HotFixRecyclerView( Context context, AttributeSet attrs, int defStyle )
        {
            super( context, attrs, defStyle );
        }
    
        @Override
        public void stopScroll()
        {
            try
            {
                super.stopScroll();
            }
            catch( NullPointerException exception )
            {
                /**
                 *  The mLayout has been disposed of before the 
                 *  RecyclerView and this stops the application 
                 *  from crashing.
                 */
            }
        }
    }
    

    Then change all references from the RecyclerView to HotFixRecyclerView. If you do use it please remove it once Android have patched this issue as it's a bit of a hack.

    • If you use recylerview inn XML don't forget to change your XML files accordingly to use com.your.package.HotFixRecyclerView instead of android.support.v7.widget.RecyclerView

提交回复
热议问题