web-dev-qa-db-ja.com

「LayoutManagerはRecyclerViewにすでにアタッチされています」エラー

レイアウトに複数のRecyclerViewを配置しようとしていますが、「LayoutManagerはすでにRecyclerViewにアタッチされています」というエラーが表示されます。

Javaコードは:

@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;
}

XMLレイアウトコードは次のとおりです。

<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>

MyLinearLayoutManagerは、SDK LinearLayoutManagerのコンテンツの折り返しの問題を解決するためにオンラインで見つけたカスタムのLinearLayoutManagerです。

1つのレイアウトで複数のRecyclerViewを使用できる方法はありますか?レイアウトごとに複数のLayoutManagerをアタッチできないようです。

どんな援助でも大歓迎です:)

32
TheoK

私もこの問題を抱えていました。私のアクティビティは、3つのフラグメントを持つタブを使用しています。3番目のタブに移動し、最初(または2番目)に戻ると、このエラーがスローされます。

何度も検索したところ、強い参照を使用していたため、ガベージコレクターである可能性があることがわかりました。

コンストラクターLinearLayoutManagerはパラメーターとして(フラグメントではなく)アクティビティを使用するため、タブの変更中、タブアクティビティはアクティブなままです。

クラスからmLinearLayoutManagerのローカルフィールドを削除し、弱参照を使用すると、この問題を取り除くことができます。

前:

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);
    }
}

私は次のように変更しました:

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()));
    }
}
69
WilliamK

新しいインスタンスを作成するだけです:

RecyclerView recyclerView = new RecyclerView(getContext());
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()))
4
Victor Ruiz C.

Daggerを介してLayoutManagerを指定すると、このエラーが発生しました。
解決策は、レイアウトマネージャーインジェクションをレイアウトマネージャーjavax.inject.Providerインジェクションに置き換えることです。

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

...

recyclerView.setLayoutManager(layoutManager.get())
2
Mikhail Sharin

私にも同じ問題があります。 LinearLayoutManagerインスタンスにnullを設定することで回避します。

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;
}
0
yinsweet

このエラーはDaggar2で発生し、LinearLayoutManagerの前にProviderを使用して単純に削除しました。

 @Inject

 Provider <LinearLayoutManager> linearLayoutManager;

 mViewDataBinding.rvResult.setLayoutManager(linearLayoutManager.get());
0
Arun Prajapati

私の場合、LinearLayoutManagerをグローバルに宣言し、LinearLayoutManagerの同じインスタンスを複数のRecyclerView'sにアタッチしようとしたため、このエラーが発生しました。

1つのLayoutManagerは1つのLayoutManagerにしか接続できないため、解決策は各RecyclerViewに異なるRecyclerviewを接続することです。

0
nimi0112