2015-10-06 71 views
0

我正在嘗試在已有的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(); 
     } 

    } 
} 

在這裏,既firstlast成爲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 

回答

0

我必須做的這些日子裏,我用這個庫類似的東西:https://github.com/timehop/sticky-headers-recyclerview

它很容易,如果你是用來RecyclerViews適配器。

+2

是的,我在該庫看起來爲好。我不相信我可以使用它,因爲它的文檔指出:*標題視圖被繪製到畫布上,而實際上並不是視圖層次結構的一部分。因此,他們不能有觸摸狀態,並且如果您嘗試異步加載圖像,可能會遇到問題。在我的情況下,除了純文本以外,標題還需要有一些狀態和附加視圖(例如一個小按鈕)。我想這個圖書館是不可能的。如果我錯了,請糾正我。 –

+0

@Krøllebølle,你是完全正確的,的確我在我的https://github.com/davideas/FlexibleAdapter項目中使用了相同的timehop​​機制,並且我正在尋找幫助,使用自定義LayoutManager以良好的方式製作粘性標題,沒有龐大的編碼,因爲SuperSlim項目已經完成(只有3400行的部分和粘頭只有!?) – Davidea

0

加入這一行的結束onBindViewHolder方法:

//configuring sticky headers 
    final LayoutManager.LayoutParams lp = LayoutManager.LayoutParams.from(holder.itemView.getLayoutParams()); 
    lp.setSlm(LinearSLM.ID); 
    lp.setFirstPosition(getHeaderPosition(position)); 
    holder.itemView.setLayoutParams(lp); 

getHeaderPosition方法返回標頭位置爲每個項目