項(xiàng)目用的是這個(gè)人的框架
https://github.com/CymChad/BaseRecyclerViewAdapterHelper
測(cè)試發(fā)現(xiàn)rv底層拋出了一個(gè)異常,不斷滑動(dòng)加載更多出現(xiàn)的
ViewHolder views must not be attached when created. Ensure that you are not passing 'true' to the attachToRoot parameter of LayoutInflater.inflate(..., boolean attachToRoot)
看了下大佬的框架好像沒(méi)人解決過(guò)這個(gè)問(wèn)題

錯(cuò)誤異常如下代碼
java.lang.IllegalStateException: ViewHolder views must not be attached when created. Ensure that you are not passing 'true' to the attachToRoot parameter of LayoutInflater.inflate(..., boolean attachToRoot)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6687)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5869)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5752)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5748)
at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2232)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1559)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1519)
at android.support.v7.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1333)
at android.support.v7.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1077)
at android.support.v7.widget.RecyclerView.scrollByInternal(RecyclerView.java:1815)
at android.support.v7.widget.RecyclerView.onTouchEvent(RecyclerView.java:3076)
at android.view.View.dispatchTouchEvent(View.java:9939)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2663)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2344)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2669)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2669)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2669)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2669)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2669)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2669)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2669)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2669)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2669)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2669)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2669)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2358)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:411)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1810)
百度搜了幾篇文章都說(shuō)

可是我看了作者的代碼本來(lái)就這樣寫

懷著好奇的跟蹤了下源碼,源碼路徑
/frameworks/support/v7/recyclerview/src/main/java/androidx/recyclerview/widget/RecyclerView.java
/**
6739 * This method calls {@link #onCreateViewHolder(ViewGroup, int)} to create a new
6740 * {@link ViewHolder} and initializes some private fields to be used by RecyclerView.
6741 *
6742 * @see #onCreateViewHolder(ViewGroup, int)
6743 */
6744 @NonNull
6745 public final VH createViewHolder(@NonNull ViewGroup parent, int viewType) {
6746 try {
6747 TraceCompat.beginSection(TRACE_CREATE_VIEW_TAG);
6748 final VH holder = onCreateViewHolder(parent, viewType);
6749 if (holder.itemView.getParent() != null) {
6750 throw new IllegalStateException("ViewHolder views must not be attached when"
6751 + " created. Ensure that you are not passing 'true' to the attachToRoot"
6752 + " parameter of LayoutInflater.inflate(..., boolean attachToRoot)");
6753 }
6754 holder.mItemViewType = viewType;
6755 return holder;
6756 } finally {
6757 TraceCompat.endSection();
6758 }
6759 }
從代碼來(lái)看holder.itemView.getParent() 不為null就會(huì)拋出這個(gè)異常,然后我再看了看final VH holder = onCreateViewHolder(parent, viewType);
可能我很久沒(méi)寫代碼,發(fā)現(xiàn)onCreateViewHolder是要自己去實(shí)現(xiàn)邏輯的
/**
6659 * Called when RecyclerView needs a new {@link ViewHolder} of the given type to represent
6660 * an item.
6661 * <p>
6662 * This new ViewHolder should be constructed with a new View that can represent the items
6663 * of the given type. You can either create a new View manually or inflate it from an XML
6664 * layout file.
6665 * <p>
6666 * The new ViewHolder will be used to display items of the adapter using
6667 * {@link #onBindViewHolder(ViewHolder, int, List)}. Since it will be re-used to display
6668 * different items in the data set, it is a good idea to cache references to sub views of
6669 * the View to avoid unnecessary {@link View#findViewById(int)} calls.
6670 *
6671 * @param parent The ViewGroup into which the new View will be added after it is bound to
6672 * an adapter position.
6673 * @param viewType The view type of the new View.
6674 *
6675 * @return A new ViewHolder that holds a View of the given view type.
6676 * @see #getItemViewType(int)
6677 * @see #onBindViewHolder(ViewHolder, int)
6678 */
6679 @NonNull
6680 public abstract VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType);
然后我又看了下作者封裝的這個(gè)方法

好奇按百度出來(lái)的博客跟了下源碼LayoutInflater源碼,的確如此

又看了下RecyclerView的ViewHolder,創(chuàng)建ViewHolder的時(shí)候會(huì)傳遞itemView

問(wèn)題可能是復(fù)用的時(shí)候調(diào)用了onCreateViewHolder,onCreateViewHolder出現(xiàn)神經(jīng)病,認(rèn)為itemView有parent,或者是rv緩存問(wèn)題,或者我分析方向不對(duì)
因?yàn)槲揖蛷?fù)現(xiàn)過(guò)2次,后面就沒(méi)復(fù)現(xiàn)了就按大佬說(shuō)緩存下,原本項(xiàng)目中沒(méi)設(shè)置setOffscreenPageLimit,后面有時(shí)間再研究,可能我比較菜
fragment在viewpager容器里來(lái)回切換,如果沒(méi)有設(shè)置,會(huì)導(dǎo)致重復(fù)實(shí)例化,重復(fù)加載數(shù)據(jù),
建議在設(shè)置一個(gè)緩存,
解決方式:給page
mViewPager.setOffscreenPageLimit(3);
為什么重復(fù)實(shí)例化會(huì)出現(xiàn)這個(gè)問(wèn)題,現(xiàn)在我的需求就是需要重新刷新這個(gè)fragment,怎么處理?