java.lang.IllegalStateException: ViewHolder views must not be attached when created. Ensure that ...

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)

出現(xiàn)這個問題,沒有報具體哪一行代碼報錯,只知道是RecyclerView的問題。
網(wǎng)上的辦法是inflater.inflate參數(shù)改為null或者false。

但不是這種情況。

搜到一個文章:
https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues/2796

發(fā)現(xiàn)他的問題是空布局被不同的RecyclerView重復(fù)利用導(dǎo)致的。

恰好我的代碼里面也有一個用到空布局的地方。

mAdapter.setHomeInfos(mHomeInfos, true);
public void setHomeInfos(ArrayList<HomeInfo> homeInfos, boolean displayEmptyView) {
setShouldDisplayEmptyView(displayEmptyView);

試了一下我的app,發(fā)現(xiàn)確實(shí)在連續(xù)兩次用到空布局的時候才會報錯。

找到這個空布局創(chuàng)建的地方

public View getEmptyView() {
        if(mEmptyView == null){
            mEmptyView = View.inflate(mContext, R.layout.common_empty_view, null);
        }
        return mEmptyView;
 }

https://github.com/CymChad/BaseRecyclerViewAdapterHelper/issues/2796這里面提供了方法:

//在重用mEmptyLayout視圖前,先將mEmptyLayout從之前對父布局中釋放出來
        ViewGroup elViewGroup = (ViewGroup)mEmptyLayout.getParent();
        if (elViewGroup != null) {
                    elViewGroup.removeView(mEmptyLayout);
        }

拿來試了一下:

public View getEmptyView() {
        ViewGroup elViewGroup = (ViewGroup)mEmptyView.getParent();
        if (elViewGroup != null) {
            elViewGroup.removeView(mEmptyView);
        }
        if(mEmptyView == null){
            mEmptyView = View.inflate(mContext, R.layout.common_empty_view, null);
        }
        return mEmptyView;
    }

發(fā)現(xiàn)這個方法可行。

最后看一下,為什么這個方法可行,先找到拋出這個錯誤的地方:

RecyclerView.java:
if (holder.itemView.getParent() != null) {
                    throw new 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)");
}

在這個itemView的父容器為null的情況下報的錯。
再看看這個itemView是哪來的。

RecyclerView.java:
public ViewHolder(@NonNull View itemView) {
            if (itemView == null) {
                throw new IllegalArgumentException("itemView may not be null");
            }
            this.itemView = itemView;
}

我的代碼里是在這傳的

public RecyclerViewHolder(View itemView) {
        super(itemView);
 }

上一步:

return new RecyclerViewHolder(getEmptyView());

最后發(fā)現(xiàn)報錯那個地方的itemView。最終就是這個getEmptyView()。

所以加的這個判斷可行。

public View getEmptyView() {
        ViewGroup elViewGroup = (ViewGroup)mEmptyView.getParent();
        if (elViewGroup != null) {
            elViewGroup.removeView(mEmptyView);
        }
        if(mEmptyView == null){
            mEmptyView = View.inflate(mContext, R.layout.common_empty_view, null);
        }
        return mEmptyView;
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容