Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ViewHolder views must not be attached when created

Tags:

I'm trying to create a simple RV that will show a TextView. This is my adapter:

public class MyRvAdapter extends RecyclerView.Adapter<MyRvAdapter.ViewHolder> {

private String[] mDataset;


public static class ViewHolder extends RecyclerView.ViewHolder {
    // each data item is just a string in this case
    public TextView mTextView;
    public ViewHolder(TextView v) {
        super(v);
        mTextView = v;
    }
}

public MyRvAdapter(String[] myDataset) {
    mDataset = myDataset;
}

@NonNull
@Override
public MyRvAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.text_row_item, parent, false);
    TextView userNameInList= v.findViewById(R.id.display_name);
    ViewHolder vh = new ViewHolder(userNameInList);
    return vh;
    }

@Override
public void onBindViewHolder(@NonNull MyRvAdapter.ViewHolder holder, int position) {
    holder.mTextView.setText(mDataset[position]);
}

@Override
public int getItemCount() {
    return mDataset.length;
}

}

text_row_item is just a FrameLayout with a TextView inside it("display_name"). This is the eror:

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)

Thank you very much!

like image 715
Nakash.i Avatar asked Jun 29 '18 10:06

Nakash.i


People also ask

What is the concept of ViewHolder?

A ViewHolder describes an item view and metadata about its place within the RecyclerView. RecyclerView. Adapter implementations should subclass ViewHolder and add fields for caching potentially expensive View. findViewById(int) results.

What is the relationship between RecyclerView adapter and RecyclerView ViewHolder?

ViewHolder is not bound to an item or the given RecyclerView. Adapter is not part of this Adapter (if this Adapter merges other adapters).

What is ViewHolder in Kotlin?

ViewHolder class which caches views associated with the default Preference layouts. A ViewHolder describes an item view and metadata about its place within the RecyclerView. Adapter implementations should subclass ViewHolder and add fields for caching potentially expensive View#findViewById(int) results.


2 Answers

Actually, your ViewHolder expects a View inflated from R.layout.text_row_item rather than a descendant of the latter. So, if you pass the inflated view the problem will be resolved.

So, you should correct your code to this:

public class MyRvAdapter extends RecyclerView.Adapter<MyRvAdapter.ViewHolder> {

    private String[] mDataset;

    public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public TextView mTextView;
        public ViewHolder(View v) {
            super(v);
            mTextView = v.findViewById(r.id.display_name);
        }
    }

    public MyRvAdapter(String[] myDataset) {
        mDataset = myDataset;
    }

    @NonNull
    @Override
    public MyRvAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.text_row_item, parent, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    @Override
    public void onBindViewHolder(@NonNull MyRvAdapter.ViewHolder holder, int position) {
        holder.mTextView.setText(mDataset[position]);
    }

    @Override
    public int getItemCount() {
        return mDataset.length;
    }
}
like image 106
Anatolii Avatar answered Sep 27 '22 18:09

Anatolii


Wait till view is created before binding.

Remove TextView userNameInList= v.findViewById(R.id.display_name); from your MyRvAdapter.ViewHolder.

And bind in ViewHolder as mTextView = v.findViewById(r.id.display_name);.

like image 40
Gokul Nath KP Avatar answered Sep 27 '22 16:09

Gokul Nath KP