"LayoutManager is already attached to a RecyclerView" error

19,519

Solution 1

I had this problem too. My Activity uses Tabs, with three fragments, when I go to third tab, and back to first (or second), this error is thrown.

After searching a lot, I found out that may be the garbage collector, because I was using a strong reference.

Since the constructor LinearLayoutManager uses the activity as the parameter (not the fragment), a Tabs Activity stays active during tabs changes.

Removing the local field in mLinearLayoutManager from the class, and using a weak reference, I could get rid of this problem:

before:

public class MyFragment1 extends Fragment
    private LinearLayoutManager linearLayoutManager;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        linearLayoutManager = new LinearLayoutManager(getActivity());
        (...)
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
        (...)
        mRecyclerView.setLayoutManager(linearLayoutManager);
    }
}

I changed to:

public class MyFragment1 extends Fragment {
    // private LinearLayoutManager linearLayoutManager;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        // linearLayoutManager = new LinearLayoutManager(getActivity());
        (...)
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        (...)
        mRecyclerView.setLayoutManager(
           new LinearLayoutManager(getActivity()));
    }
}

Solution 2

Just need to create a new instance:

RecyclerView recyclerView = new RecyclerView(getContext());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()))

Solution 3

I faced this error when providing LayoutManager via Dagger.
The solution is to replace layout manager injection with layout manager javax.inject.Provider injection.

@Inject
lateinit var layoutManager: Provider<RecyclerView.LayoutManager>

...

recyclerView.setLayoutManager(layoutManager.get())

Solution 4

I have the same problem as well. I work around it by setting null to LinearLayoutManager instance.

public class MyFragment extends Fragment {
protected LinearLayoutManager mLinearLayoutManager;
...

@Override
public void onDestroy() {
    super.onDestroy();
    if(mLinearLayoutManager != null) // Workaround: android.support.v7.widget.LinearLayoutManager is already attached to a RecyclerView
        mLinearLayoutManager = null;
}

Solution 5

In my case, I had declared a LinearLayoutManager globally and I was trying to attach the same instance of LinearLayoutManager to multiple RecyclerView's so I was getting this error.

The Solution is to attach different LayoutManager to each RecyclerView because one LayoutManager can only be attached to one Recyclerview.

Share:
19,519

Related videos on Youtube

TheoK
Author by

TheoK

Updated on September 14, 2022

Comments

  • TheoK
    TheoK over 1 year

    I am trying to have multiple RecyclerViews in a layout but I get the following error: "LayoutManager is already attached to a RecyclerView"

    The Java code is:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_squad, container, false);
    
        Activity parentActivity = getActivity();
        final ObservableScrollView scrollView = (ObservableScrollView) view.findViewById(R.id.squad_scrollview);
    
        final RecyclerView gkRecyclerView = (RecyclerView) view.findViewById(R.id.gk_recycler);
        final RecyclerView coachRecyclerView = (RecyclerView) view.findViewById(R.id.coach_recycler);
    
        coachRecyclerView.setAdapter(new SquadRecyclerAdapter(parentActivity, getSquadDummyData(0)));
        coachRecyclerView.setLayoutManager(new MyLinearLayoutManager(parentActivity, LinearLayoutManager.VERTICAL, false));
        coachRecyclerView.setHasFixedSize(false);
    
        gkRecyclerView.setAdapter(new SquadRecyclerAdapter(parentActivity, getSquadDummyData(1)));
        gkRecyclerView.setLayoutManager(new MyLinearLayoutManager(parentActivity, LinearLayoutManager.VERTICAL, false));
        gkRecyclerView.setHasFixedSize(false);
    
        scrollView.setTouchInterceptionViewGroup((ViewGroup) parentActivity.findViewById(R.id.container));
    
        if (parentActivity instanceof ObservableScrollViewCallbacks) {
            scrollView.setScrollViewCallbacks((ObservableScrollViewCallbacks) parentActivity);
        }
    
        return view;
    }
    

    The XML layout code is:

    <com.github.ksoichiro.android.observablescrollview.ObservableScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/squad_scrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="@dimen/margin_medium"
        >
    
        <LinearLayout
            android:id="@+id/squad_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/seasons_scrollview"
            android:divider="@drawable/nav_bar_divider"
            android:elevation="@dimen/card_elevation"
            android:orientation="vertical"
            android:showDividers="middle">
    
            <LinearLayout
                android:id="@+id/coach_group"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingBottom="@dimen/margin_small"
                android:paddingLeft="@dimen/margin_standard"
                android:paddingRight="@dimen/margin_standard"
                android:paddingTop="@dimen/margin_small">
    
                <TextView
                    android:id="@+id/squad_coach_header"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Coach"
                    android:textSize="@dimen/text_size_standard" />
    
                <android.support.v7.widget.RecyclerView
                    android:id="@+id/coach_recycler"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingTop="@dimen/margin_small"
                    android:paddingBottom="@dimen/margin_small"
                    android:scrollbars="none">
    
                </android.support.v7.widget.RecyclerView>
    
            </LinearLayout>
    
            <LinearLayout
                android:id="@+id/gk_group"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingBottom="@dimen/margin_small"
                android:paddingLeft="@dimen/margin_standard"
                android:paddingRight="@dimen/margin_standard"
                android:paddingTop="@dimen/margin_small">
    
                <TextView
                    android:id="@+id/squad_gk_header"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Goalkeepers"
                    android:textSize="@dimen/text_size_standard" />
    
                <android.support.v7.widget.RecyclerView
                    android:id="@+id/gk_recycler"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:paddingTop="@dimen/margin_small"
                    android:paddingBottom="@dimen/margin_small"
                    android:scrollbars="none">
    
                </android.support.v7.widget.RecyclerView>
    
            </LinearLayout>
    
            <LinearLayout
                android:id="@+id/def_group"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingBottom="@dimen/margin_small"
                android:paddingLeft="@dimen/margin_standard"
                android:paddingRight="@dimen/margin_standard"
                android:paddingTop="@dimen/margin_small">
    
                <TextView
                    android:id="@+id/squad_def_header"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Defense"
                    android:textSize="@dimen/text_size_standard" />
    
            </LinearLayout>
    
            <LinearLayout
                android:id="@+id/mid_group"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingBottom="@dimen/margin_small"
                android:paddingLeft="@dimen/margin_standard"
                android:paddingRight="@dimen/margin_standard"
                android:paddingTop="@dimen/margin_small">
    
                <TextView
                    android:id="@+id/squad_mid_header"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Midfielders"
                    android:textSize="@dimen/text_size_standard" />
    
            </LinearLayout>
    
            <LinearLayout
                android:id="@+id/for_group"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingBottom="@dimen/margin_small"
                android:paddingLeft="@dimen/margin_standard"
                android:paddingRight="@dimen/margin_standard"
                android:paddingTop="@dimen/margin_small">
    
                <TextView
                    android:id="@+id/squad_for_header"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Forwards"
                    android:textSize="@dimen/text_size_standard" />
    
            </LinearLayout>
    
    
        </LinearLayout>
    
    
    </com.github.ksoichiro.android.observablescrollview.ObservableScrollView>
    

    The MyLinearLayoutManager is a custom LinearLayoutManager I found online in order to solve the wrap-content issue of the SDK LinearLayoutManager.

    Is there any way I can have multiple RecyclerViews in a single layout? It seems that I cannot attach more than one LayoutManagers per layout.

    Any assistance would be very welcome :)

    • Eduardo Naveda
      Eduardo Naveda almost 9 years
      Can you update with the source of that LayoutManager?
    • TheoK
      TheoK almost 9 years
      I tried the SDK LinearLayoutManager but still the same error. So it is not the custom LayoutManager the issue.
  • Zvi
    Zvi about 8 years
    Not only it works, I also managed to change the layout based on the user choice while the fragment is displayed, just by clicking on a button.
  • Muhammad
    Muhammad over 7 years
    Thank you so much!
  • iDeveloper
    iDeveloper almost 7 years
    Perfect Answer :)
  • komal akhani
    komal akhani over 6 years
    Perfect Answer..Thanks:)
  • Kyo Huu
    Kyo Huu over 5 years
    is there other way ? because I need too use LayoutManager as a global object in my fragment
  • Kyo Huu
    Kyo Huu over 5 years
    ok I found the answer. I just need to call recyclerView.getLayoutManager(). tks
  • Daniel Wilson
    Daniel Wilson almost 5 years
    Woah thank you, so a Provider makes a new one every time get() is called...hmm
  • Den
    Den over 4 years
    What if I need LayoutManager as in my Fragment class? I'm using it for scrollListeners for example
  • NickUnuchek
    NickUnuchek over 4 years
    Provider creates new instance of layoutManager
  • RamPrasadBismil
    RamPrasadBismil over 4 years
    Should we use a bindingAdapter instead of constructor initialization?
  • Dario Brux
    Dario Brux over 4 years
    Perfect answer!!
  • MarkWang
    MarkWang over 3 years
    @KyoHuu or just remember set null in onDestoryView() of fragment.
  • Nathaniel Hoyt
    Nathaniel Hoyt over 3 years
    it's so rare, but so satisfying, when an answer like this one addresses the problem i'm having so specifically and provides such a simple, straightforward solution. thank you!