【发布时间】:2015-10-06 19:46:38
【问题描述】:
我正在尝试在我已经存在的RecyclerView 中实现粘性标头,它有标头,但没有标头。 SuperSLiM 看起来很有希望,但我无法将该库集成到我现有的代码中。源代码后面的示例运行良好,我已经尝试适应这一点并按照SuperSLiM wiki 上的步骤进行操作。
我的RecyclerView 最初是空的。我遇到的问题是当我第一次将项目添加到我的适配器并在这些项目上调用 Adapter.notifyItemChanged() 时。完成此操作后,我会被扔进LayoutManager.onItemsUpdated()。该方法如下所示:
public void onItemsUpdated(RecyclerView recyclerView, int positionStart, int itemCount)
{
super.onItemsUpdated(recyclerView, positionStart, itemCount);
View first = this.getChildAt(0); // null
View last = this.getChildAt(this.getChildCount() - 1); // null
if(positionStart + itemCount > this.getPosition(first)) // NullPointerException
{
if(positionStart <= this.getPosition(last))
{
this.requestLayout();
}
}
}
在这里,first 和 last 都变为 null,因此在下面的行中抛出了 NullPointerException。请注意,onItemsUpdated() 在示例应用程序中没有调用,因此此处不会发生此错误。我不知道为什么; Adapter.notifyItemChanged() 在示例应用中也被调用。
可能是什么问题?
我的片段类:
请注意,在下面的代码中切换回正常的RecyclerView.LayoutManager 会使一切正常工作。
public class MyFragment extends Fragment
{
private MyRecyclerView mRecyclerView;
private MyAdapter mAdapter;
// private RecyclerView.LayoutManager mLayoutManager; // Normal RecyclerView.LayoutManager working just fine
private LayoutManager mLayoutManager; // SuperSLiM LayoutManager crashing
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.my_fragment, container, false);
MyActivity myActivity = (MyActivity) rootView.getContext();
mRecyclerView = (MyRecyclerView) rootView.findViewById(R.id.my_recyclerview);
// mLayoutManager = new LinearLayoutManager(myActivity); // Normal RecyclerView.LayoutManager
mLayoutManager = new LayoutManager(myActivity); // SuperSLiM LayoutManager
mAdapter = new MyAdapter(myActivity);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mAdapter);
myActivity.onShoppingListCreated();
return rootView;
}
public void onDataSetChanged()
{
if (mAdapter == null)
{
return;
}
mAdapter.notifyDataSetChanged();
}
// This is called multiple times after a button press at some point.
// Thereafter, if it is the SuperSLiM LayoutManager that is in play,
// the error explained above occurs.
public void onItemChanged(int position)
{
if (mAdapter == null)
{
return;
}
mAdapter.notifyItemChanged(position);
}
}
崩溃时的堆栈跟踪:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.ViewGroup$LayoutParams android.view.View.getLayoutParams()' on a null object reference
at android.support.v7.widget.RecyclerView$LayoutManager.getPosition(RecyclerView.java:6097)
at com.tonicartos.superslim.LayoutManager.onItemsUpdated(LayoutManager.java:542)
at android.support.v7.widget.RecyclerView$5.dispatchUpdate(RecyclerView.java:665)
at android.support.v7.widget.RecyclerView$5.onDispatchSecondPass(RecyclerView.java:675)
at android.support.v7.widget.AdapterHelper.consumeUpdatesInOnePass(AdapterHelper.java:547)
at android.support.v7.widget.RecyclerView.processAdapterUpdatesAndSetAnimationFlags(RecyclerView.java:2530)
at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:2318)
at android.view.View.measure(View.java:17547)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:875)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17547)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1488)
at android.view.View.measure(View.java:17547)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17547)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
at android.view.View.measure(View.java:17547)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:727)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:463)
at android.view.View.measure(View.java:17547)
at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:868)
at android.view.View.measure(View.java:17547)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
at android.support.v7.internal.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:124)
at android.view.View.measure(View.java:17547)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17547)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
at android.view.View.measure(View.java:17547)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17547)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2615)
at android.view.View.measure(View.java:17547)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2015)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1173)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1379)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventRe
【问题讨论】:
标签: android android-recyclerview superslim