在Marshmallow中使用GridLayoutManager遇到Android RecyclerView的问题

3

你好,我在使用Marshmallow中的GridLayoutManager和recyclerview时遇到了问题。我使用片段来制作列表,以下是代码:

private RecyclerView mRecyclerView;
private RecyclerCategoryAdapter mListAdapter;
private GridLayoutManager mLayoutManager;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_category, container, false);
    mSwipeLayout = (SwipeRefreshLayout) v.findViewById(R.id.swipe_container);
    mRecyclerView = (RecyclerView) v.findViewById(R.id.category_recyclerview);
    mRecyclerView.setHasFixedSize(true);

    mLayoutManager = new GridLayoutManager(container.getContext(), 2);
    mRecyclerView.setLayoutManager(mLayoutManager);
    mLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            if ( mListAdapter != null && mListAdapter.isPositionFooter(position) || mListAdapter.isPositionHeader(position)) {
                return mLayoutManager.getSpanCount();
            } else {
                return 1;
            }
        }
    });
    mRecyclerView.setLayoutManager(mLayoutManager);

    return v;
}

如果列表中有页眉或页脚,我尝试使内容填充屏幕宽度,否则应该是2列网格布局。在调用getSpanSize(int位置)后的第一个if语句中应用程序崩溃。

Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.memebox.us.adapter.recycler.RecyclerCategoryAdapter.isPositionHeader(int)' on a null object reference
   at com.memebox.us.fragment.CategoryFragment$1.getSpanSize(CategoryFragment.java:96)
   at android.support.v7.widget.GridLayoutManager$SpanSizeLookup.getSpanGroupIndex(GridLayoutManager.java:804)
   at android.support.v7.widget.GridLayoutManager.getSpanGroupIndex(GridLayoutManager.java:357)
   at android.support.v7.widget.GridLayoutManager.getRowCountForAccessibility(GridLayoutManager.java:128)
   at android.support.v7.widget.RecyclerView$LayoutManager.onInitializeAccessibilityNodeInfo(RecyclerView.java:7659)
   at android.support.v7.widget.RecyclerView$LayoutManager.onInitializeAccessibilityNodeInfo(RecyclerView.java:7619)
   at android.support.v7.widget.RecyclerViewAccessibilityDelegate.onInitializeAccessibilityNodeInfo(RecyclerViewAccessibilityDelegate.java:59)
   at android.support.v4.view.AccessibilityDelegateCompat$AccessibilityDelegateJellyBeanImpl$1.onInitializeAccessibilityNodeInfo(AccessibilityDelegateCompat.java:233)
   at android.support.v4.view.AccessibilityDelegateCompatJellyBean$1.onInitializeAccessibilityNodeInfo(AccessibilityDelegateCompatJellyBean.java:61)
   at android.view.View.onInitializeAccessibilityNodeInfo(View.java:6619)
   at android.view.View.createAccessibilityNodeInfoInternal(View.java:6580)
   at android.view.View$AccessibilityDelegate.createAccessibilityNodeInfo(View.java:23704)
   at android.view.View.createAccessibilityNodeInfo(View.java:6563)
   at android.view.accessibility.AccessibilityRecord.setSource(AccessibilityRecord.java:145)
   at android.view.accessibility.AccessibilityRecord.setSource(AccessibilityRecord.java:119)
   at android.view.View.onInitializeAccessibilityEventInternal(View.java:6517)
   at android.view.View$AccessibilityDelegate.onInitializeAccessibilityEvent(View.java:23616)
   at android.support.v4.view.AccessibilityDelegateCompatIcs.onInitializeAccessibilityEvent(AccessibilityDelegateCompatIcs.java:92)
   at android.support.v4.view.AccessibilityDelegateCompat$AccessibilityDelegateIcsImpl.onInitializeAccessibilityEvent(AccessibilityDelegateCompat.java:179)
   at android.support.v4.view.AccessibilityDelegateCompat.onInitializeAccessibilityEvent(AccessibilityDelegateCompat.java:419)
   at android.support.v7.widget.RecyclerViewAccessibilityDelegate.onInitializeAccessibilityEvent(RecyclerViewAccessibilityDelegate.java:65)
   at android.support.v4.view.AccessibilityDelegateCompat$AccessibilityDelegateJellyBeanImpl$1.onInitializeAccessibilityEvent(AccessibilityDelegateCompat.java:228)
   at android.support.v4.view.AccessibilityDelegateCompatJellyBean$1.onInitializeAccessibilityEvent(AccessibilityDelegateCompatJellyBean.java:56)
   at android.view.View.onInitializeAccessibilityEvent(View.java:6503)
   at android.view.View.sendAccessibilityEventUncheckedInternal(View.java:6364)
   at android.view.View$AccessibilityDelegate.sendAccessibilityEventUnchecked(View.java:23555)
   at android.support.v4.view.AccessibilityDelegateCompatIcs.sendAccessibilityEventUnchecked(AccessibilityDelegateCompatIcs.java:117)
   at android.support.v4.view.AccessibilityDelegateCompat$AccessibilityDelegateIcsImpl.sendAccessibilityEventUnchecked(AccessibilityDelegateCompat.java:210)
   at android.support.v4.view.AccessibilityDelegateCompat.sendAccessibilityEventUnchecked(AccessibilityDelegateCompat.java:358)
   at android.support.v4.view.AccessibilityDelegateCompat$AccessibilityDelegateJellyBeanImpl$1.sendAccessibilityEventUnchecked(AccessibilityDelegateCompat.java:255)
   at android.support.v4.view.AccessibilityDelegateCompatJellyBean$1.sendAccessibilityEventUnchecked(AccessibilityDelegateCompatJellyBean.java:82)
   at android.view.View.sendAccessibilityEventUnchecked(View.java:6347)
   at android.support.v7.widget.RecyclerView.sendAccessibilityEventUnchecked(RecyclerView.java:2649)
   at android.view.View$SendViewStateChangedAccessibilityEvent.run(View.java:23741)
   at android.view.View$SendViewStateChangedAccessibilityEvent.runOrPost(View.java:23774)
   at android.view.View.notifyViewAccessibilityStateChangedIfNeeded(View.java:9367)
   at android.view.View.onFocusChanged(View.java:6232)
   at android.view.View.clearFocusInternal(View.java:6124)
   at android.view.View.unFocus(View.java:6169)
   at android.view.ViewGroup.unFocus(ViewGroup.java:1010)
   at android.view.ViewGroup.unFocus(ViewGroup.java:1012)
   at android.view.ViewGroup.unFocus(ViewGroup.java:1012)
   at android.view.ViewGroup.unFocus(ViewGroup.java:1012)
   at android.view.ViewGroup.requestChildFocus(ViewGroup.java:750)
   at android.view.ViewGroup.requestChildFocus(ViewGroup.java:756)
   at android.view.ViewGroup.requestChildFocus(ViewGroup.java:756)
   at android.view.View.handleFocusGainInternal(View.java:5973)
   at android.view.ViewGroup.handleFocusGainInternal(ViewGroup.java:730)
   at android.view.View.requestFocusNoSearch(View.java:9053)
   at android.view.View.requestFocus(View.java:9032)
   at android.view.ViewGroup.requestFocus(ViewGroup.java:3048)
   at android.view.ViewGroup.onRequestFocusInDescendants(ViewGroup.java:3093)
   at android.view.ViewGroup.requestFocus(ViewGroup.java:3049)
   at android.view.ViewGroup.onRequestFocusInDescendants(ViewGroup.java:3093)
   at android.view.ViewGroup.requestFocus(ViewGroup.java:3049)
   at android.view.View.requestFocus(View.java:8999)
   at android.view.View.requestFocus(View.java:8978)
   at android.support.v4.widget.DrawerLayout.dispatchOnDrawerOpened(DrawerLayout.java:750)
   at android.support.v4.widget.DrawerLayout.updateDrawerState(DrawerLayout.java:700)
   at android.support.v4.widget.DrawerLayout$ViewDragCallback.onViewDragStateChanged(DrawerLayout.java:1833)
   at android.support.v4.widget.ViewDragHelper.setDragState(ViewDragHelper.java:874)
   at android.support.v4.widget.ViewDragHelper$2.run(ViewDragHelper.java:335)
   at android.os.Handler.handleCallback(Handler.java:739)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:158)
   at android.app.ActivityThread.main(ActivityThread.java:7229)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

以下是我正在使用的适配器代码:

public boolean isPositionHeader(int position){
    return position == 0;
}

public boolean isPositionFooter(int position){
    return position == getItemCount() -1 ;
}

@Override
public int getItemCount() {
    return mProductList != null ? mProductList.size() + 2 : 0;
}

我尝试在列表中始终添加两个更多的项目,一个作为标题,一个作为页脚,并始终将这两个视图添加到列表中(作为全宽内容)。

我不明白为什么消息中会出现“RecyclerCategoryAdapter.isPositionHeader(int)' on a null object reference”。

在调用方法“isPositionHeader(position)”之前,我检查了适配器是否为空,而且对于方法isPositionHeader似乎没有任何可能为空的情况。

这只发生在Android手机6.0和6.1版本上。但从未发生在我的手机上(我的手机是Nexus 5x)。所以这并不总是发生。

由于我刚开始将ListView替换为RecyclerView,我需要一些建议。有人可以帮我解决这个问题吗?或者有人遇到同样的问题吗?

如果还需要附加更多代码,请告诉我。

谢谢

1个回答

2
您的if语句有一个小问题。请将其更改为以下内容:
if (mListAdapter != null && (mListAdapter.isPositionFooter(position) || mListAdapter.isPositionHeader(position)))

谢谢,我会尝试在下一个版本中应用它。但是据我所知,Java从左到右检查语句,并且一旦某个条件失败就不会检查下一个语句。难道我不知道正确的事实吗? - Android Rabbit
是的,它确实可以,但你之前的写法相当于 if ((mListAdapter != null && mListAdapter.IsPositionFooter(position)) || mListAdapter.IsPositionHeader(position))。正如你所看到的,即使 mListAdapter = null,它也会检查位置是否为 header。如果它们都是 &&,那么它将按照你最初的想法运行。 - Dan Harms

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接