Programing

RecyclerView를 NestedScrollView에 넣는 방법은 무엇입니까?

crosscheck 2021. 1. 8. 21:18
반응형

RecyclerView를 NestedScrollView에 넣는 방법은 무엇입니까?


의 생성으로 NestedScrollView 당신이 한 그 구현 같은 다른 스크롤 뷰 내부 뷰를 스크롤 넣을 수 있습니다 NestedScrollingChildNestedScrollingParent을 올바르게.

(이것은 나쁜 디자인 패턴이 아닙니다. "Ian Lake (Google에서)는 실제로 RecyclerView여기에 중첩 된 스크롤 뷰를 넣을 것을 권장 합니다 : plus.google.com/u/0/+AndroidDevelopers/posts/9kZ3SsXdT2T")

내가 데려 가고 싶다는 RecyclerView을 내부 NestedScrollView 다행히 RecyclerView 구현 NestedScrollingChild 당신이 안에 넣을 수 NestedScrollView .

public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild

이 게시물을 읽었습니다.

NestedScrollView 내에서 RecyclerView를 사용하는 방법은 무엇입니까?

CoordinatorLayout 내에서 NestedScrollView, RecyclerView (Horizontal)를 사용한 NestedScrolling

그러나 가장 많이 투표 된 솔루션의 문제는 모든 항목을 호출 RecyclerView한다는 것입니다. 예를 들어 무한 RecyclerView이고 사용자가 목록 끝에 도달하면 네트워크 요청을하고 해당 솔루션으로 RecyclerView서버를 반복적으로 호출합니다. 의 마지막 항목에 자동으로 도달하기 때문입니다 RecyclerView.

어쨌든, 나는 어떻게 설정 매개 변수를 둘 수 있도록 RecyclerView내부 NestedScrollView. (실제로 나는 nestedscrollview의 하나의 차일드로 FrameLayout이 나 RelativeLayout의 같은 뷰 그룹을 넣고 싶어하고 나는 FrameLayout이 나 RelativeLayout의 내부 recyclerview을 데려 가고 싶다는)

RecyclerView안에 넣었을 때 NestedScrollView표시 할 것이 없습니다.


샘플 프로젝트를 생성하기 위해 cheesesquare 를 사용 CheeseDetailActivity하고 RecyclerView를 갖도록 변경할 수 있습니다 .


BNK의 대답은 정확하지 않지만 BNK는 많은 노력을 기울였습니다. 그래서 나는 그에게 현상금을 수여합니다. 여전히 좋은 솔루션을 찾고 있습니다 ....


다음은 나의 새로운 업데이트 된 답변입니다.

<android.support.v4.widget.NestedScrollView
        android:id="@+id/scrollview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <android.support.v7.widget.CardView
                android:id="@+id/cardview1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="@dimen/card_margin">

                <LinearLayout
                    style="@style/Widget.CardContent"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="Info CardView1"
                        android:textAppearance="@style/TextAppearance.AppCompat.Title" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/cheese_ipsum" />

                </LinearLayout>

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

            <android.support.v7.widget.CardView
                android:id="@+id/cardview2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/cardview1"
                android:layout_margin="@dimen/card_margin">

                <LinearLayout
                    style="@style/Widget.CardContent"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="Info CardView2"
                        android:textAppearance="@style/TextAppearance.AppCompat.Title" />

                    <TextView
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:text="@string/cheese_ipsum" />

                </LinearLayout>

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

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recyclerview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/cardview2"
                android:clipToPadding="false"
                android:paddingTop="0dp"/>

        </RelativeLayout>

    </android.support.v4.widget.NestedScrollView>

활동 중 :

        RecyclerViewAdapter recyclerViewAdapter = new RecyclerViewAdapter(true); // true: with header
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);            
        final MyLinearLayoutManager layoutManager = new MyLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false, getScreenHeight(this));
        // final CustomLinearLayoutManager layoutManager = new CustomLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(recyclerViewAdapter);  
        // recyclerView.setNestedScrollingEnabled(false); // Disables scrolling for RecyclerView, however, CustomLinearLayoutManager used instead of MyLinearLayoutManager

또한 My GitHub의 샘플 프로젝트로 업데이트했습니다.

스크린 샷 :

여기에 이미지 설명 입력



여기에 더 많은 데이터를로드해야하는 경우에만 서버를 호출하는 솔루션이 있습니다. 이런 식으로 NestedScrollView 내에 끝없는 RecyclerView 및 기타 많은 뷰를 넣을 수 있습니다. 저에게는 잘 작동합니다.

1. NestedSrollView 에서 스크롤 이벤트를 처리 할 EndlessParentScrollListener 클래스를 만듭니다 .

public abstract class EndlessParentScrollListener implements NestedScrollView.OnScrollChangeListener {
        // The current offset index of data you have loaded
        private int currentPage = 0;
        // The total number of items in the dataset after the last load
        private int previousTotalItemCount = 0;
        // True if we are still waiting for the last set of data to load.
        private boolean loading = true;
        // Sets the starting page index
        private int startingPageIndex = 0;
        // The minimum amount of pixels to have below your current scroll position
        // before loading more.
        private int visibleThresholdDistance = 300;

        RecyclerView.LayoutManager mLayoutManager;

        public EndlessParentScrollListener(RecyclerView.LayoutManager layoutManager) {
            this.mLayoutManager = layoutManager;
        }

        @Override
        public void onScrollChange(NestedScrollView scrollView, int x, int y, int oldx, int oldy) {
            // We take the last son in the scrollview
            View view = scrollView.getChildAt(scrollView.getChildCount() - 1);
            int distanceToEnd = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY()));

            int totalItemCount = mLayoutManager.getItemCount();
            // If the total item count is zero and the previous isn't, assume the
            // list is invalidated and should be reset back to initial state
            if (totalItemCount < previousTotalItemCount) {
                this.currentPage = this.startingPageIndex;
                this.previousTotalItemCount = totalItemCount;
                if (totalItemCount == 0) {
                    this.loading = true;
                }
            }

            // If it’s still loading, we check to see if the dataset count has
            // changed, if so we conclude it has finished loading and update the current page
            // number and total item count.
            if (loading && (totalItemCount > previousTotalItemCount)) {
                loading = false;
                previousTotalItemCount = totalItemCount;
            }

            // If it isn’t currently loading, we check to see if we have breached
            // the visibleThreshold and need to reload more data.
            // If we do need to reload some more data, we execute onLoadMore to fetch the data.
            // threshold should reflect how many total columns there are too
            if (!loading && distanceToEnd <= visibleThresholdDistance) {
                currentPage++;
                onLoadMore(currentPage, totalItemCount);
                loading = true;
            }
        }

        // Defines the process for actually loading more data based on page
        public abstract void onLoadMore(int page, int totalItemsCount);
    }

2. 리스너 설정

private void initRecycler() {  
        //TODO init recycler adapter here

        recycler.setNestedScrollingEnabled(false);          
        LinearLayoutManager _layoutManager = new LinearLayoutManager(this);
        recycler.setLayoutManager(_layoutManager);
        NestedScrollView scrollView = (NestedScrollView) findViewById(R.id.scrollView);
        scrollView.setOnScrollChangeListener(new EndlessParentScrollListener(_layoutManager) {
                @Override
                public void onLoadMore(int page, int totalItemsCount) {                     
                    if (loadedItemCount < serverItemsCount)
                        customLoadMoreDataFromApi();
                }
            });
        customLoadMoreDataFromApi();
    }

누군가 유용하다고 생각하는 경우 짧은 xml :

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/background_light"
        android:fitsSystemWindows="true">


        <android.support.design.widget.AppBarLayout>
            ...
        </android.support.design.widget.AppBarLayout>

        <android.support.v4.widget.NestedScrollView
            android:id="@+id/scrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fitsSystemWindows="true"
            android:scrollbars="vertical"
            android:scrollbarAlwaysDrawVerticalTrack="true"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                android:scrollbarAlwaysDrawVerticalTrack="false"
                android:scrollbars="vertical">

                <!-- some views goes here-->

                <android.support.v7.widget.RecyclerView
                    android:id="@+id/recyclerFeed"
                    android:scrollbars="vertical"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

                <!-- and possibly here-->

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

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

따라서 NestedScrollView 안에 RecyclerView를 직접 넣으면 불행히도 아무것도 표시되지 않습니다. 그러나 NestedScrollView 내부에 간접적으로 recyclerview를 넣는 방법이 있습니다. frameLayout을 타사로 사용하여 recyclerview를 유지하십시오.

이것은 활동 클래스 에 중첩 된 recyclerview를 보유하는 프레임 레이아웃입니다 .

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:context=".ExampleFragment"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true"
            >
        </android.support.v4.widget.NestedScrollView>
   </FrameLayout>

프래그먼트를 프레임 레이아웃에 넣습니다 (코드는 활동 클래스 내에 있음 ).

 ExampleFragment exampleFragment = new ExampleFragment();

    FragmentManager fm = getSupportFragmentManager();
    FragmentTransaction ft = fm.beginTransaction();
    ft.add(R.id.container, exampleFragment);
    ft.commit();

당신에 exampleFragment , 당신은 다음 recyclerview을 넣을 수 있습니다.

<?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/post_container"
        android:background="#E0E0E0">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/my_recycler_view"
                android:scrollbars="vertical"

                android:layout_width="match_parent"
                android:layout_height="match_parent">
            </android.support.v7.widget.RecyclerView>


    </RelativeLayout>

다음은 조각 코드입니다.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    super.onCreateView(inflater, container, savedInstanceState);
            llLayout = (RelativeLayout) inflater.inflate(R.layout.example_fragment_layout, container, false);
                    mRecyclerView = (RecyclerView) llLayout.findViewById(R.id.my_recycler_view);

다음은 필요한 CheeseSquare XML 레이아웃입니다.

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/detail_backdrop_height"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:fitsSystemWindows="true">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            android:fitsSystemWindows="true"
            app:contentScrim="?attr/colorPrimary"
            app:expandedTitleMarginStart="48dp"
            app:expandedTitleMarginEnd="64dp">

            <ImageView
                android:id="@+id/backdrop"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="centerCrop"
                android:fitsSystemWindows="true"
                app:layout_collapseMode="parallax" />

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_collapseMode="pin" />

        </android.support.design.widget.CollapsingToolbarLayout>

    </android.support.design.widget.AppBarLayout>

   <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:context=".ExampleFragment"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <android.support.v4.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true"
            >
        </android.support.v4.widget.NestedScrollView>
   </FrameLayout>

    <android.support.design.widget.FloatingActionButton
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        app:layout_anchor="@id/appbar"
        app:layout_anchorGravity="bottom|right|end"
        android:src="@drawable/ic_discuss"
        android:layout_margin="@dimen/fab_margin"
        android:clickable="true"/>

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

참조 URL : https://stackoverflow.com/questions/33330388/how-to-put-recyclerview-inside-nestedscrollview

반응형