RecyclerView не перерабатывает представления при использовании внутри NestedScrollView

Я использую RecyclerView внутри NestedScrollView. Также я установил setNestedScrollingEnabled в false для recyclerview

для поддержки более низкого 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();
            }

        }

    });

Ps: Я установил load more для просмотра с прокруткой, потому что recyclerview делает это постоянно и не остановить!

Любая помощь приветствуется


person MAY3AM    schedule 02.06.2016    source источник
comment
Можете ли вы объяснить причину, по которой вы добавили RecyclerView внутрь NestedScrollView?   -  person romtsn    schedule 05.06.2016
comment
@ rom4ek stackoverflow.com/questions/37437161/   -  person MAY3AM    schedule 05.06.2016
comment
@ MAY3AM обновите свой код и xml   -  person appukrb    schedule 07.06.2016
comment
@appukrb готово, код и xml добавлены   -  person MAY3AM    schedule 07.06.2016
comment
какую версию recyclerview вы скомпилировали в своем Gradle?   -  person Khairul Alam Licon    schedule 09.06.2016
comment
@ MAY3AM пробовали ли вы решение, предложенное Реханом для stackoverflow.com/questions/37437161/?   -  person Pr38y    schedule 09.06.2016
comment
@ Pr38y Я не хочу обновлять свой адаптер   -  person MAY3AM    schedule 09.06.2016
comment
NestedScrollView рисует весь дочерний элемент, поэтому, если RecyclerView был использован внутри NestedScrollView, весь элемент адаптера будет загружен в первый раз сам. Лучшим подходом будет использование только RecyclerView и использование getItmeViewType для возврата cardView if(position==0) в adapter. как предложил Рехан.   -  person Pr38y    schedule 09.06.2016
comment
@ Pr38y Я пробовал это раньше, и у меня возникли проблемы с производительностью, этот подход может быть нормальным при использовании LinearLayoutManager, но в моем случае с StaggeredGridLayoutManager это не помогло.   -  person MAY3AM    schedule 09.06.2016
comment
Обычно я использую @ Pr38y. с какой проблемой производительности вы столкнулись?   -  person Tin Tran    schedule 11.06.2016
comment
Примечание: не используйте ViewCompat, используйте RecyclerView#setNestedScrollingEnabled. RecyclerView поступает из библиотек поддержки и уже переносит свои функции на более старые API.   -  person natario    schedule 13.06.2016
comment
@ MAY3AM вы нашли решение?   -  person Kevin Robatel    schedule 25.07.2016
comment
@Kevinrob Нет еще !! :(   -  person MAY3AM    schedule 25.07.2016
comment
Привет @ MAY3AM. Есть какое-нибудь решение? У меня есть несколько горизонтальной прокрутки RecyclerView внутри NestedScrollView. Добавили setNestedScrollingEnabled (true) и столкнулись с той же проблемой (recyclerview не перерабатывает)   -  person Wijay Sharma    schedule 03.01.2018
comment
@WijaySharma Привет, к сожалению, у меня ничего нет :(   -  person MAY3AM    schedule 13.01.2018


Ответы (2)


Это потому, что у нас есть представление ресайклера, которое имеет поведение прокрутки внутри представления прокрутки. (прокрутите внутри свитка)

Я думаю, что лучший способ решить эту проблему - использовать profileCardview в качестве заголовка в представлении ресайклера, а затем удалить вложенное представление прокрутки.

Если бы это было представление списка, то это было бы так же просто, как listView.addHeaderView (profileCardView), но для представления Recycler нет эквивалента addheadview. Следовательно, вы можете обратиться к приведенной ниже ссылке, чтобы изменить свою реализацию.

Есть ли эквивалент addHeaderView для RecyclerView?

person Arpit Ratan    schedule 10.06.2016

Для RecyclerView или ListView высота должна быть постоянной, потому что, если она не будет постоянного размера, то как она будет управлять максимальным количеством видимых строк в памяти. Попробуйте изменить атрибут RecyclerView android:layout_height="match_parent" или фиксированную высоту (например, "300dp" - по мере необходимости) вместо "wrap_content". Это должно улучшить ваше управление памятью.

person Neo    schedule 19.06.2016
comment
@CliveJefferies Установка layout_height на фиксированный размер уменьшит повторное рисование при обновлении вложенного представления. Вы вроде как говорите, не волнуйтесь - не нужно перерисовывать это представление, если мои подпредставления изменятся, потому что они имеют фиксированный размер. Теоретически вы могли бы сказать, что это может уменьшить объем памяти, но в основном это устранит сборку мусора, блокирующую пользовательский интерфейс, что сделает ваше приложение более плавным. - person Arturs Vancans; 08.03.2019