2016-09-20 70 views
2

我做了一個自定義RecyclerView爲了在我的應用程序的列表中啓用分頁。我在恢復狀態時發生崩潰。也許這次崩潰與支持庫中的一個已知錯誤有關,但從技術上講,它已在支持庫版本24.0.0https://code.google.com/p/android/issues/detail?id=196430中得到解決,但它仍然崩潰。保存狀態自定義RecyclerView

也許我做錯了什麼?我有一個BadParcelableException ClassNotFoundException when unmarshalling: android.support.v7.widget.RecyclerView$SavedStateHere嘗試重新創建SavedState。

這裏是我的CustomRecyclerView控制器內部SavedState類:

public static class SavedState extends RecyclerView.BaseSavedState { 

    public boolean isLastPage; 
    public boolean isLoading; 
    public int maxPages; 
    public int pageSize; 
    public int currentPage; 
    public int firstVisibleItem; 
    public Parcelable layoutManagerState; 

    public SavedState(Parcelable superState) { 
     super(superState); 
    } 

    public SavedState(Parcel source) { 
     super(source); 
     this.isLastPage = source.readByte() == 1; 
     this.isLoading = source.readByte() == 1; 
     this.maxPages = source.readInt(); 
     this.pageSize = source.readInt(); 
     this.currentPage = source.readInt(); 
     this.firstVisibleItem = source.readInt(); 
     this.layoutManagerState = source.readParcelable(LinearLayoutManager.SavedState.class.getClassLoader()); 
    } 

    @Override 
    public void writeToParcel(Parcel dest, int flags) { 
     super.writeToParcel(dest, flags); 
     dest.writeByte((byte) (isLastPage ? 1 : 0)); 
     dest.writeByte((byte) (isLoading ? 1 : 0)); 
     dest.writeInt(maxPages); 
     dest.writeInt(pageSize); 
     dest.writeInt(currentPage); 
     dest.writeInt(firstVisibleItem); 
     dest.writeParcelable(layoutManagerState, flags); 
    } 

    public static final Creator<SavedState> CREATOR = new Creator<SavedState>() { 
     @Override 
     public SavedState createFromParcel(Parcel source) { 
      return new SavedState(source); 
     } 

     @Override 
     public SavedState[] newArray(int size) { 
      return new SavedState[size]; 
     } 
    }; 
} 

這裏就是我節省,並在控制器恢復狀態:

public Parcelable saveState(Parcelable superState) { 
    SavedState savedState  = new SavedState(superState); 
    savedState.isLastPage  = this.isLastPage; 
    savedState.isLoading  = this.isLoading; 
    savedState.maxPages   = this.maxPages; 
    savedState.pageSize   = this.pageSize; 
    savedState.currentPage  = this.currentPage; 
    savedState.firstVisibleItem = this.firstVisibleItemPosition; 

    if (layoutManager != null) { 
     savedState.layoutManagerState = layoutManager.onSaveInstanceState(); 
    } 

    return savedState; 
} 

public Parcelable restoreState(SavedState savedState) { 

    this.isLastPage     = savedState.isLastPage; 
    this.isLoading     = savedState.isLoading; 
    this.maxPages     = savedState.maxPages; 
    this.pageSize     = savedState.pageSize; 
    this.currentPage    = savedState.currentPage; 
    this.firstVisibleItemPosition = savedState.firstVisibleItem; 

    return savedState.layoutManagerState; 
} 

這裏是onSaveInstanceStateonRestoreInstanceState自定義RecyclerView中的實現:

@Override 
    protected Parcelable onSaveInstanceState() { 

     return controller.saveState(super.onSaveInstanceState()); 
    } 

    @Override 
    protected void onRestoreInstanceState(Parcelable state) { 

     if (state instanceof EndlessRecyclerViewController.SavedState) { 

      EndlessRecyclerViewController.SavedState savedState = (EndlessRecyclerViewController.SavedState) state; 

      Parcelable layoutManagerState = controller.restoreState(savedState); 

      getLayoutManager().onRestoreInstanceState(layoutManagerState); 
      super.onRestoreInstanceState(savedState.getSuperState()); 
     } 
     else 
      super.onRestoreInstanceState(state); 
    } 

我也嘗試從支持AbsSavedState延伸SavedState,但仍然崩潰。我不確定是否需要撥打LinearLayoutManageronSaveInstanceState ...

謝謝!

+0

而不是延伸BaseSaveState,在recyclerview簡單替代的onSaveInstanceState,並保存在包你需要的值,並覆蓋onrestoreinstancestate和恢復這些值 –

+0

但是在CustomViews中,您沒有在onSaveInstanceState中收到Bundle,您必須使用您的數據創建一個自定義的狀態類,並將它作爲Parcelable返回到onSaveInstanceState中,對吧? – antonicg

回答

0

最後我解決了使用AbsSavedState(所以我從它擴展SavedState類)支持庫版本24.2.1。並改變從接收Parcel對象constructor

public SavedState(Parcel source) { 
    super(source); 
    //... 
} 

到:

public SavedState(Parcel source) { 
    super(source, LinearLayoutManager.class.getClassLoader()); 
    //... 
}