web-dev-qa-db-ja.com

NestedScrollView内でご使用の場合、RecyclerViewはビューをリサイクルしません

RecyclerView内でNestedScrollViewを使用しています。また、setNestedScrollingEnabledに対してrecyclerviewをfalseに設定します

下位APIをサポートするため

ViewCompat.setNestedScrollingEnabled(mRecyclerView, false);

今!ユーザーがビューをスクロールすると、すべてのものは問題ないように見えますが、!!! recyclerviewのビューはリサイクルされません!!!ヒープサイズが急速に増加します。

更新:RecyclerViewレイアウトマネージャーはStaggeredLayoutManager

fragment_profile.xml

<Android.support.design.widget.CoordinatorLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/coordinator"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical" >

        <Android.support.design.widget.AppBarLayout
            Android:id="@+id/appbar"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" >
        </Android.support.design.widget.AppBarLayout>

        <Android.support.v4.widget.SwipeRefreshLayout
            Android:id="@+id/profileSwipeRefreshLayout"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent" >

                <!-- RecyclerView and NestedScrollView -->
                <include layout="@layout/fragment_profile_details" />

        </Android.support.v4.widget.SwipeRefreshLayout>

</Android.support.design.widget.CoordinatorLayout>

fragment_profile_details.xml

<LinearLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/rootLayout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    Android:orientation="vertical" >

        <Android.support.v4.widget.NestedScrollView
            Android:id="@+id/nested_scrollbar"
            Android:layout_width="match_parent"
            Android:layout_height="match_parent"
            Android:layout_gravity="fill_vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            Android:fillViewport="true"
            Android:scrollbars="none" >

                <LinearLayout
                    Android:id="@+id/nested_scrollbar_linear"
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content"
                    Android:descendantFocusability="blocksDescendants"
                    Android:orientation="vertical" >

                        <Android.support.v7.widget.CardView
                            Android:id="@+id/profileCardview"
                            Android:layout_width="match_parent"
                            Android:layout_height="wrap_content"
                            app:cardBackgroundColor="@color/card_backgroind"
                            app:cardCornerRadius="0dp"
                            app:cardElevation="0dp" >

                            <!-- Profile related stuff like avatar and etc. --->

                        </Android.support.v7.widget.CardView>

                        <Android.support.v7.widget.RecyclerView
                            Android:id="@+id/list_view"
                            Android:layout_width="match_parent"
                            Android:layout_height="wrap_content"
                            Android:layout_marginBottom="@dimen/four"
                            Android:layout_marginEnd="@dimen/four"
                            Android:layout_marginLeft="@dimen/four"
                            Android:layout_marginRight="@dimen/four"
                            Android:layout_marginStart="@dimen/four"
                            Android:layout_marginTop="@dimen/four"
                            app:layout_behavior="@string/appbar_scrolling_view_behavior"
                            Android:clipToPadding="false" />

                </LinearLayout>
        </Android.support.v4.widget.NestedScrollView>
</LinearLayout>

ProfileFragment.Java

mAdapter        = new MainAdapter(getActivity(), glide, Data);

listView        = (RecyclerView) view.findViewById(R.id.list_view);

ViewCompat.setNestedScrollingEnabled(listView, false);  
listView.setAdapter(mAdapter);

mStaggeredLM    = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
mStaggeredLM.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);

listView.setLayoutManager(mStaggeredLM);

mScroll.setOnScrollChangeListener(new OnScrollChangeListener() {

        @Override
        public void onScrollChange(NestedScrollView arg0, int arg1, int arg2, int arg3, int arg4) {

            View view   = (View) mScroll.getChildAt(mScroll.getChildCount() - 1);
            int diff    = (view.getBottom() - ( mScroll.getHeight() + mScroll.getScrollY()));

            if(diff == 0){

                int visibleItemCount            = mStaggeredLM.getChildCount();
                int totalItemCount              = mStaggeredLM.getItemCount();

                int[] lastVisibleItemPositions  = mStaggeredLM.findLastVisibleItemPositions(null);
                int lastVisibleItemPos  = getLastVisibleItem(lastVisibleItemPositions);

                Log.e("getChildCount", String.valueOf(visibleItemCount));
                Log.e("getItemCount", String.valueOf(totalItemCount));
                Log.e("lastVisibleItemPos", String.valueOf(lastVisibleItemPos));

                if ((visibleItemCount + 5) >= totalItemCount) {

                    mLoadMore.setVisibility(View.VISIBLE);
                    Log.e("LOG", "Last Item Reached!");
                }

                mMore = true;
                mFresh = false;
                mRefresh = false;
                getPosts();
            }

        }

    });

P.s:recyclerviewは継続的に実行し、停止できないため、ビューをスクロールするためにさらにロードを設定しました!

どんな助けでも大歓迎です

54
MAY3AM

これは、スクロールビュー内でスクロール動作を行うリサイクラビューがあるためです。 (スクロール内をスクロール)

この問題を解決する最良の方法は、profileCardviewをリサイクラビューのヘッダーとして使用し、ネストされたスクロールビューを削除することだと思います。

リストビューの場合、listView.addHeaderView(profileCardView)と同じくらい簡単ですが、Recyclerビューにはaddheadviewに相当するものはありません。したがって、以下のリンクを参照して実装を変更できます。

RecyclerViewに相当するaddHeaderViewはありますか?

8
Arpit Ratan

RecyclerViewまたはListViewの場合、高さが一定である必要があります。これは、サイズが一定でない場合、メモリ内の可視行の最大数を管理する方法です。 RecyclerView属性を変更してみてくださいAndroid:layout_height="match_parent" の代わりに "wrap_content"。メモリ管理が改善されるはずです。

2
Neo