programing

ScrollView 내부의 RecyclerView가 작동하지 않습니다.

padding 2023. 8. 6. 09:53
반응형

ScrollView 내부의 RecyclerView가 작동하지 않습니다.

다을포함레는구합고니다려현하을웃을 .RecyclerView그리고.ScrollView같은 레이아웃으로

레이아웃 템플릿:

<RelativeLayout>
    <ScrollView android:id="@+id/myScrollView">

       <unrelated data>...</unrealated data>

       <android.support.v7.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/my_recycler_view" />
    </ScrollView>   
</RelativeLayout>

例문:마막요지스수있다습니 .ScrollView.

제가 시도한 것들:

  1. 의 카드 ScrollView(지금은ScrollView를 포함합니다.RecyclerView - 를 볼 수 . - 음다시 까볼카 수있 다니습 를드지 간▁)다 니있▁up 습▁the▁card ▁see수▁can▁the.RecyclerView.
  2. 처음에 생각했던 것은 이것을 구현하는 것이었습니다.ViewGroup용사를 RecyclerViewScrollView의 뷰 중 는 여서뷰유중하는입니다.CardView하지만 저는 정확히 같은 결과를 얻었습니다.ScrollView.

사용하다NestedScrollViewScrollView

자세한 내용은 NestedScrollView 참조 문서를 참조하십시오.

가추를 합니다.recyclerView.setNestedScrollingEnabled(false);의 신에게에.RecyclerView

에 늦었다는 것을 , 에 대한 수정을 한 후에도 이 문제는 여전히 합니다.android.support.v7.widget.RecyclerView

가 지금 있는 는 제가받는문제는입니다.RecyclerView와 함께layout_height=wrap_content에서 가 되는 모든 ScrollViewMashmallow 및 Nugat+(API 23, 24, 25) 버전에서만 발생합니다.
Replacing (업데이트: 교체업)ScrollView와 함께android.support.v4.widget.NestedScrollView모든 버전에서 작동합니다.왠지 승인된 솔루션 테스트를 놓쳤습니다.이것을 내 github 프로젝트에 데모로 추가했습니다.)

여러 가지 방법을 시도한 후 이 문제를 해결할 수 있는 해결 방법을 찾았습니다.

다음은 제 레이아웃 구조입니다.

<ScrollView>
  <LinearLayout> (vertical - this is the only child of scrollview)
     <SomeViews>
     <RecyclerView> (layout_height=wrap_content)
     <SomeOtherViews>

해결 방법은 다음과 같습니다.RecyclerView와 함께RelativeLayout내가 이 해결책을 어떻게 찾았는지 묻지 마!!!¯\_(ツ)_/¯

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

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

</RelativeLayout>

전체 예제는 GitHub 프로젝트에서 사용할 수 있습니다. - https://github.com/amardeshbd/android-recycler-view-wrap-content

다음은 문제 해결 방법을 보여주는 데모 스크린캐스트입니다.

Screencast

비록 그 권고가

스크롤 가능한 뷰를 다른 스크롤 가능한 뷰 안에 넣으면 안 됩니다.

좋은 조언이지만, 재활용품 뷰에 고정된 높이를 설정하면 잘 작동할 것입니다.

어댑터 항목 레이아웃의 높이를 알고 있으면 Recycler View의 높이를 계산할 수 있습니다.

int viewHeight = adapterItemSize * adapterData.size();
recyclerView.getLayoutParams().height = viewHeight;

RecyclerView에 대한 고정 높이 설정이 (나와 같은) 다른 사용자에게 적용되지 않는 경우 고정 높이 솔루션에 추가한 내용은 다음과 같습니다.

mRecyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        int action = e.getAction();
        switch (action) {
            case MotionEvent.ACTION_MOVE:
                rv.getParent().requestDisallowInterceptTouchEvent(true);
                break;
        }
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView rv, MotionEvent e) {

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
});

새로운 Android 지원 라이브러리 23.2는 이러한 문제를 해결합니다. 이제 wrap_content를 높이로 설정할 수 있습니다.RecyclerView올바르게 작동합니다.

Android 지원 라이브러리 23.2

RecyclerViews넣어도 좋습니다.ScrollViews그들이 스스로 스크롤하지 않는 한.이런 경우에는 고정된 높이로 하는 것이 타당합니다.

적절한 해결책은 다음과 같습니다.wrap_content에서.RecyclerView 높를지한다사정용구의현자음이정▁▁a▁▁implement를 높이는 다음 구현LinearLayoutManager포장을 적절하게 처리할 수 있는.

이 선형 레이아웃 관리자를 프로젝트에 복사합니다. 링크

그럼 포장해주세요.RecyclerView:

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

다음과 같이 설정합니다.

RecyclerView list = (RecyclerView)findViewById(R.id.list);
list.setHasFixedSize(true);
list.setLayoutManager(new com.example.myapp.LinearLayoutManager(list.getContext()));
list.setAdapter(new MyViewAdapter(data));

편집: 이는 스크롤링에 문제를 일으킬 수 있습니다.RecyclerView을 훔칠 수 .ScrollView의 터치 이벤트.내 해결책은 그냥 버리는 것이었습니다.RecyclerView대체로LinearLayout하위 뷰를 프로그래밍 방식으로 부풀려서 레이아웃에 추가합니다.

위해서ScrollView당신은 사용할 수 있습니다.fillViewport=true그리고 만들기layout_height="match_parent" 아와같이를 넣어주세요.RecyclerView내부:

<ScrollView
    android:fillViewport="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/llOptions">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rvList"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
</ScrollView>

코드를 통해 높이를 더 이상 조정할 필요가 없습니다.

,RecyclerView東京의 NestedScrollView 및활화성을 합니다.recyclerView.setNestedScrollingEnabled(false);스크롤이 잘 작동할 것입니다.
하지만, 문제가 있습니다.

RecyclerView 재활용 안 함

를 들어, 여러분의 를들어, 당의신이 있습니다.RecyclerView)로 표시됩니다.NestedScrollView또는ScrollView) 100개의 항목을 가지고 있습니다.
Activity런칭, 100개의 아이템이 (onCreateViewHolder그리고.onBindViewHolder100개의 항목이 동시에 호출됩니다.).
예를 들어, 각 항목에 대해 API => 생성된 활동 -> 100개의 이미지가 로드됩니다.
활동 시작 속도가 느려지고 느려집니다.
가능한 해결책:
사용을 생각하고 있습니다.RecyclerView다중 활자로

하지만, 당신의 경우에는, 단지 몇 가지 항목이 있습니다.RecyclerView그리고 재활용하거나 재활용하지 않는 것은 성능에 큰 영향을 미치지 않습니다, 당신은 사용할 수 있습니다.RecyclerView東京의 ScrollView한 경우에는

이거 먹어봐요.답변이 매우 늦었지만, 미래에 누구든 확실히 도와줍니다.

  1. 을 합니다.ScrollViewNestedScrollView:

    <android.support.v4.widget.NestedScrollView>
    
        <android.support.v7.widget.RecyclerView 
            ...
            ... />
    
    </android.support.v4.widget.NestedScrollView>
    
  2. 으로 업데이트합니다.Recyclerview:

    recyclerView.setNestedScrollingEnabled(false); 
    recyclerView.setHasFixedSize(false);
    

계산중중RecyclerView, 것이 사용자 지정을 사용하는 것이 좋습니다.LayoutManager.

입니다.ListView,GridView,RecyclerView할 때 때 다른 뷰의 하위로 추가할 때 스크롤할 때 높이를 계산하지 못했습니다.그래서 그것을 무시하는 것.onMeasure방법이 문제를 해결할 것입니다.

기본 레이아웃 관리자를 다음으로 교체하십시오.

public class MyLinearLayoutManager extends android.support.v7.widget.LinearLayoutManager {

    private static boolean canMakeInsetsDirty = true;
    private static Field insetsDirtyField = null;

    private static final int CHILD_WIDTH = 0;
    private static final int CHILD_HEIGHT = 1;
    private static final int DEFAULT_CHILD_SIZE = 100;

    private final int[] childDimensions = new int[2];
    private final RecyclerView view;

    private int childSize = DEFAULT_CHILD_SIZE;
    private boolean hasChildSize;
    private int overScrollMode = ViewCompat.OVER_SCROLL_ALWAYS;
    private final Rect tmpRect = new Rect();

    @SuppressWarnings("UnusedDeclaration")
    public MyLinearLayoutManager(Context context) {
        super(context);
        this.view = null;
    }

    @SuppressWarnings("UnusedDeclaration")
    public MyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
        this.view = null;
    }

    @SuppressWarnings("UnusedDeclaration")
    public MyLinearLayoutManager(RecyclerView view) {
        super(view.getContext());
        this.view = view;
        this.overScrollMode = ViewCompat.getOverScrollMode(view);
    }

    @SuppressWarnings("UnusedDeclaration")
    public MyLinearLayoutManager(RecyclerView view, int orientation, boolean reverseLayout) {
        super(view.getContext(), orientation, reverseLayout);
        this.view = view;
        this.overScrollMode = ViewCompat.getOverScrollMode(view);
    }

    public void setOverScrollMode(int overScrollMode) {
        if (overScrollMode < ViewCompat.OVER_SCROLL_ALWAYS || overScrollMode > ViewCompat.OVER_SCROLL_NEVER) {
            throw new IllegalArgumentException("Unknown overscroll mode: " + overScrollMode);
        }

        if (this.view == null) throw new IllegalStateException("view == null");

        this.overScrollMode = overScrollMode;
        ViewCompat.setOverScrollMode(view, overScrollMode);
    }

    public static int makeUnspecifiedSpec() {
        return View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    }

    @Override
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {
        final int widthMode = View.MeasureSpec.getMode(widthSpec);
        final int heightMode = View.MeasureSpec.getMode(heightSpec);

        final int widthSize = View.MeasureSpec.getSize(widthSpec);
        final int heightSize = View.MeasureSpec.getSize(heightSpec);

        final boolean hasWidthSize = widthMode != View.MeasureSpec.UNSPECIFIED;
        final boolean hasHeightSize = heightMode != View.MeasureSpec.UNSPECIFIED;

        final boolean exactWidth = widthMode == View.MeasureSpec.EXACTLY;
        final boolean exactHeight = heightMode == View.MeasureSpec.EXACTLY;

        final int unspecified = makeUnspecifiedSpec();

        /** 
         * In case of exact calculations for both dimensions let's 
         * use default "onMeasure" implementation. 
         */
        if (exactWidth && exactHeight) {
            super.onMeasure(recycler, state, widthSpec, heightSpec);
            return;
        }

        final boolean vertical = getOrientation() == VERTICAL;

        initChildDimensions(widthSize, heightSize, vertical);

        int width = 0;
        int height = 0;

        /**
         * It's possible to get scrap views in recycler which are bound to old (invalid) 
         * adapter entities. This happens because their invalidation happens after "onMeasure" 
         * method. As a workaround let's clear the recycler now (it should not cause 
         * any performance issues while scrolling as "onMeasure" is never called whiles scrolling).
         */
        recycler.clear();

        final int stateItemCount = state.getItemCount();
        final int adapterItemCount = getItemCount();

        /**
         * Adapter always contains actual data while state might contain old data
         * (f.e. data before the animation is done).  As we want to measure the view 
         * with actual data we must use data from the adapter and not from  the state.
         */
        for (int i = 0; i < adapterItemCount; i++) {
            if (vertical) {
                if (!hasChildSize) {
                    if (i < stateItemCount) {
                        /**
                         * We should not exceed state count, otherwise we'll get IndexOutOfBoundsException. 
                         * For such items we will use previously calculated dimensions.
                         */
                        measureChild(recycler, i, widthSize, unspecified, childDimensions);
                    } else {
                        logMeasureWarning(i);
                    }
                }
                height += childDimensions[CHILD_HEIGHT];
                if (i == 0) {
                    width = childDimensions[CHILD_WIDTH];
                }
                if (hasHeightSize && height >= heightSize) {
                    break;
                }
            } else {
                if (!hasChildSize) {
                    if (i < stateItemCount) {
                        /**
                         * We should not exceed state count, otherwise we'll get IndexOutOfBoundsException. 
                         * For such items we will use previously calculated dimensions.
                         */
                        measureChild(recycler, i, unspecified, heightSize, childDimensions);
                    } else {
                        logMeasureWarning(i);
                    }
                }
                width += childDimensions[CHILD_WIDTH];
                if (i == 0) {
                    height = childDimensions[CHILD_HEIGHT];
                }
                if (hasWidthSize && width >= widthSize) {
                    break;
                }
            }
        }

        if (exactWidth) {
            width = widthSize;
        } else {
            width += getPaddingLeft() + getPaddingRight();
            if (hasWidthSize) {
                width = Math.min(width, widthSize);
            }
        }

        if (exactHeight) {
            height = heightSize;
        } else {
            height += getPaddingTop() + getPaddingBottom();
            if (hasHeightSize) {
                height = Math.min(height, heightSize);
            }
        }

        setMeasuredDimension(width, height);

        if (view != null && overScrollMode == ViewCompat.OVER_SCROLL_IF_CONTENT_SCROLLS) {
            final boolean fit = (vertical && (!hasHeightSize || height < heightSize))
                || (!vertical && (!hasWidthSize || width < widthSize));

            ViewCompat.setOverScrollMode(view, fit ? ViewCompat.OVER_SCROLL_NEVER : ViewCompat.OVER_SCROLL_ALWAYS);
        }
    }

    private void logMeasureWarning(int child) {
        if (BuildConfig.DEBUG) {
            Log.w("MyLinearLayoutManager", "Can't measure child #" + child + ", previously used dimensions will be reused." +
                "To remove this message either use #setChildSize() method or don't run RecyclerView animations");
        }
    }

    private void initChildDimensions(int width, int height, boolean vertical) {
        if (childDimensions[CHILD_WIDTH] != 0 || childDimensions[CHILD_HEIGHT] != 0) {
            /** Already initialized, skipping. */
            return;
        }
        if (vertical) {
            childDimensions[CHILD_WIDTH] = width;
            childDimensions[CHILD_HEIGHT] = childSize;
        } else {
            childDimensions[CHILD_WIDTH] = childSize;
            childDimensions[CHILD_HEIGHT] = height;
        }
    }

    @Override
    public void setOrientation(int orientation) {
        /** Might be called before the constructor of this class is called. */
        //noinspection ConstantConditions
        if (childDimensions != null) {
            if (getOrientation() != orientation) {
                childDimensions[CHILD_WIDTH] = 0;
                childDimensions[CHILD_HEIGHT] = 0;
            }
        }
        super.setOrientation(orientation);
    }

    public void clearChildSize() {
        hasChildSize = false;
        setChildSize(DEFAULT_CHILD_SIZE);
    }

    public void setChildSize(int childSize) {
        hasChildSize = true;
        if (this.childSize != childSize) {
            this.childSize = childSize;
            requestLayout();
        }
    }

    private void measureChild(RecyclerView.Recycler recycler, int position, int widthSize, int heightSize, int[] dimensions) {
        final View child;
        try {
            child = recycler.getViewForPosition(position);
        } catch (IndexOutOfBoundsException e) {
            if (BuildConfig.DEBUG) {
                Log.w("MyLinearLayoutManager", "MyLinearLayoutManager doesn't work well with animations. Consider switching them off", e);
            }
            return;
        }

        final RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) child.getLayoutParams();

        final int hPadding = getPaddingLeft() + getPaddingRight();
        final int vPadding = getPaddingTop() + getPaddingBottom();

        final int hMargin = p.leftMargin + p.rightMargin;
        final int vMargin = p.topMargin + p.bottomMargin;

        /** We must make insets dirty in order calculateItemDecorationsForChild to work. */
        makeInsetsDirty(p);
        /** This method should be called before any getXxxDecorationXxx() methods. */
        calculateItemDecorationsForChild(child, tmpRect);

        final int hDecoration = getRightDecorationWidth(child) + getLeftDecorationWidth(child);
        final int vDecoration = getTopDecorationHeight(child) + getBottomDecorationHeight(child);

        final int childWidthSpec = getChildMeasureSpec(widthSize, hPadding + hMargin + hDecoration, p.width, canScrollHorizontally());
        final int childHeightSpec = getChildMeasureSpec(heightSize, vPadding + vMargin + vDecoration, p.height, canScrollVertically());

        child.measure(childWidthSpec, childHeightSpec);

        dimensions[CHILD_WIDTH] = getDecoratedMeasuredWidth(child) + p.leftMargin + p.rightMargin;
        dimensions[CHILD_HEIGHT] = getDecoratedMeasuredHeight(child) + p.bottomMargin + p.topMargin;

        /** As view is recycled let's not keep old measured values. */
        makeInsetsDirty(p);
        recycler.recycleView(child);
    }

    private static void makeInsetsDirty(RecyclerView.LayoutParams p) {
        if (!canMakeInsetsDirty) return;

        try {
            if (insetsDirtyField == null) {
                insetsDirtyField = RecyclerView.LayoutParams.class.getDeclaredField("mInsetsDirty");
                insetsDirtyField.setAccessible(true);
            }
            insetsDirtyField.set(p, true);
        } catch (NoSuchFieldException e) {
            onMakeInsertDirtyFailed();
        } catch (IllegalAccessException e) {
            onMakeInsertDirtyFailed();
        }
    }

    private static void onMakeInsertDirtyFailed() {
        canMakeInsetsDirty = false;
        if (BuildConfig.DEBUG) {
            Log.w("MyLinearLayoutManager", "Can't make LayoutParams insets dirty, decorations measurements might be incorrect");
        }
    }
}

업데이트: 중첩 스크롤을 지원하는 NestedScrollView 및 RecyclerView와 같은 위젯이 있으므로 이 답변은 구식입니다.

스크롤 가능한 뷰를 다른 스크롤 가능한 뷰 안에 넣으면 안 됩니다!

저는 당신이 당신의 주요 레이아웃을 재활용자 뷰로 만들고 당신의 뷰를 재활용자 뷰의 항목으로 넣을 것을 제안합니다.

이 예제에서는 재활용기 뷰 어댑터 내부에서 여러 뷰를 사용하는 방법을 보여 줍니다.예제에 대한 링크

의 이줄에니을에 이 하세요.RecyclerView 보기xml 파일:

android:nestedScrollingEnabled="false"

그리고 당신의RecyclerView유연한 높이로 부드럽게 스크롤됩니다.

도움이 되길 바랍니다.

는 것 같습니다.NestedScrollView그러면 문제가 해결됩니다.

이 레이아웃을 사용하여 테스트했습니다.

<android.support.v4.widget.NestedScrollView
    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/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

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

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

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

    </LinearLayout>

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

그리고 문제없이 작동합니다.

저도 같은 문제를 겪고 있었습니다.그게 제가 노력한 것이고 효과가 있습니다.나의 xml과 java 코드를 공유합니다.이것이 누군가에게 도움이 되기를 바랍니다.

여기 xml이 있습니다.

<?xml version="1.0" encoding="utf-8"?>

< NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/iv_thumbnail"
            android:layout_width="match_parent"
            android:layout_height="200dp" />

        <TextView
            android:id="@+id/tv_description"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Description" />

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Buy" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Reviews" />
        <android.support.v7.widget.RecyclerView
            android:id="@+id/rc_reviews"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

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

    </LinearLayout>
</NestedScrollView >

여기 관련 자바 코드가 있습니다.그것은 매력적으로 작동합니다.

LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setNestedScrollingEnabled(false);

CustomLayoutManager를 사용하여 RecyclerView Scrolling을 비활성화했습니다.또한 Recycler View를 WrapContent로 사용하지 말고 0dp, Weight=1로 사용합니다.

public class CustomLayoutManager extends LinearLayoutManager {
    private boolean isScrollEnabled;

    // orientation should be LinearLayoutManager.VERTICAL or HORIZONTAL
    public CustomLayoutManager(Context context, int orientation, boolean isScrollEnabled) {
        super(context, orientation, false);
        this.isScrollEnabled = isScrollEnabled;
    }

    @Override
    public boolean canScrollVertically() {
        //Similarly you can customize "canScrollHorizontally()" for managing horizontal scroll
        return isScrollEnabled && super.canScrollVertically();
    }
}

RecyclerView에서 CustomLayoutManager 사용:

CustomLayoutManager mLayoutManager = new CustomLayoutManager(getBaseActivity(), CustomLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(mLayoutManager);
        ((DefaultItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false); 
        recyclerView.setAdapter(statsAdapter);

UI XML:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background_main"
    android:fillViewport="false">


    <LinearLayout
        android:id="@+id/contParentLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

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

            <edu.aku.family_hifazat.libraries.mpchart.charts.PieChart
                android:id="@+id/chart1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="@dimen/x20dp"
                android:minHeight="@dimen/x300dp">

            </edu.aku.family_hifazat.libraries.mpchart.charts.PieChart>


        </FrameLayout>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">


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


    </LinearLayout>


</ScrollView>

의 목적은.RecyclerView▁for다▁to▁compens니▁is것을 보상하는 것입니다.ListView그리고.ScrollView실제 작업을 수행하는 대신 다음을 수행합니다.가지고 있는 것.RecyclerView순식간에ScrollView저는 오직 a만 갖는 것을 제안합니다.RecyclerView많은 종류의 아이들을 다룰 수 있는.

이렇게 하면 효과가 있습니다.

recyclerView.setNestedScrollingEnabled(false);

먼사용야합니다해를 해야 합니다.NestedScrollViewScrollView 리고그 을것그를 .RecyclerView東京의 NestedScrollView.

사용자 지정 레이아웃 클래스를 사용하여 화면 높이와 너비를 측정합니다.

public class CustomLinearLayoutManager extends LinearLayoutManager {

public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
    super(context, orientation, reverseLayout);
}

private int[] mMeasuredDimension = new int[2];

@Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
                      int widthSpec, int heightSpec) {
    final int widthMode = View.MeasureSpec.getMode(widthSpec);
    final int heightMode = View.MeasureSpec.getMode(heightSpec);
    final int widthSize = View.MeasureSpec.getSize(widthSpec);
    final int heightSize = View.MeasureSpec.getSize(heightSpec);
    int width = 0;
    int height = 0;
    for (int i = 0; i < getItemCount(); i++) {
        if (getOrientation() == HORIZONTAL) {
            measureScrapChild(recycler, i,
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    heightSpec,
                    mMeasuredDimension);

            width = width + mMeasuredDimension[0];
            if (i == 0) {
                height = mMeasuredDimension[1];
            }
        } else {
            measureScrapChild(recycler, i,
                    widthSpec,
                    View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
                    mMeasuredDimension);
            height = height + mMeasuredDimension[1];
            if (i == 0) {
                width = mMeasuredDimension[0];
            }
        }
    }
    switch (widthMode) {
        case View.MeasureSpec.EXACTLY:
            width = widthSize;
        case View.MeasureSpec.AT_MOST:
        case View.MeasureSpec.UNSPECIFIED:
    }

    switch (heightMode) {
        case View.MeasureSpec.EXACTLY:
            height = heightSize;
        case View.MeasureSpec.AT_MOST:
        case View.MeasureSpec.UNSPECIFIED:
    }

    setMeasuredDimension(width, height);
}

private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
                               int heightSpec, int[] measuredDimension) {
    View view = recycler.getViewForPosition(position);
    recycler.bindViewToPosition(view, position);
    if (view != null) {
        RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
        int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
                getPaddingLeft() + getPaddingRight(), p.width);
        int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
                getPaddingTop() + getPaddingBottom(), p.height);
        view.measure(childWidthSpec, childHeightSpec);
        measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
        measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
        recycler.recycleView(view);
    }
}
}

그리고 다음의 활동/분절에 아래 코드를 구현합니다.RecyclerView:

 final CustomLinearLayoutManager layoutManager = new CustomLinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);

    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setAdapter(mAdapter);

    recyclerView.setNestedScrollingEnabled(false); // Disables scrolling for RecyclerView, CustomLinearLayoutManager used instead of MyLinearLayoutManager
    recyclerView.setHasFixedSize(false);

    recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            int visibleItemCount = layoutManager.getChildCount();
            int totalItemCount = layoutManager.getItemCount();
            int lastVisibleItemPos = layoutManager.findLastVisibleItemPosition();
            Log.i("getChildCount", String.valueOf(visibleItemCount));
            Log.i("getItemCount", String.valueOf(totalItemCount));
            Log.i("lastVisibleItemPos", String.valueOf(lastVisibleItemPos));
            if ((visibleItemCount + lastVisibleItemPos) >= totalItemCount) {
                Log.i("LOG", "Last Item Reached!");
            }
        }
    });

ScrollView는 RecyclerView입니다.를 행높를다설로정됩면니다하음으이됩으로 설정하면 됩니다.android:layout_height="wrap_content".

파티에 늦어서 죄송합니다만, 말씀하신 경우에 딱 맞는 다른 해결책이 있는 것 같습니다.

만약 당신이 재활용품 뷰 안에서 재활용품 뷰를 사용한다면, 그것은 완벽하게 잘 작동합니다.제가 직접 사용해봤는데 느림도 없고 육포도 전혀 없는 것 같습니다.이것이 좋은 방법인지 아닌지는 잘 모르겠지만 여러 재활용품 보기를 중첩하고 중첩된 스크롤 보기도 느려집니다.하지만 이것은 잘 작동하는 것 같습니다.한 번 해보세요.이것으로 둥지를 틀어도 괜찮을 거라고 확신해요.

하기 위한 또 은 이제문를위또방은식접근다른한해기결하은방을 사용하는 입니다.ConstraintLayout東京의 ScrollView:

<ScrollView>
  <ConstraintLayout> (this is the only child of ScrollView)
    <...Some Views...>
    <RecyclerView> (layout_height=wrap_content)
    <...Some Other Views...>

하지만 저는 여전히 고수할 것입니다.androidx.core.widget.NestedScrollView 양페이용이 제안한 접근법.

재활용품 뷰 높이를 wrap_content로 설정해 볼 수 있습니다.제 경우에는 잘 작동합니다.스크롤 뷰에서 2개의 다른 재활용품 뷰로 시도 중입니다.

가장 좋은 해결책은 에 보관한 다음 하나의 보기를 SrcollView에 유지하는 것입니다.예를

형식 -

<ScrollView> 
  <Another View>
       <RecyclerView>
       <TextView>
       <And Other Views>
  </Another View>
</ScrollView>

예.

<ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView           
              android:text="any text"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"/>


        <TextView           
              android:text="any text"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"/>
 </ScrollView>

여러 뷰가 있는 ScrollView의 다른 예

<ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:orientation="vertical"
            android:layout_weight="1">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/imageView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="#FFFFFF"
                />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingHorizontal="10dp"
                android:orientation="vertical">

                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/CategoryItem"
                    android:textSize="20sp"
                    android:textColor="#000000"
                    />

                <TextView
                    android:textColor="#000000"
                    android:text="₹1000"
                    android:textSize="18sp"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>
                <TextView
                    android:textColor="#000000"
                    android:text="so\nugh\nos\nghs\nrgh\n
                    sghs\noug\nhro\nghreo\nhgor\ngheroh\ngr\neoh\n
                    og\nhrf\ndhog\n
                    so\nugh\nos\nghs\nrgh\nsghs\noug\nhro\n
                    ghreo\nhgor\ngheroh\ngr\neoh\nog\nhrf\ndhog"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"/>

             </LinearLayout>

        </LinearLayout>

</ScrollView>

단지 디자인 목적으로만 그것을 하려고 하는 사람들을 위해 - 놔둡니다.앱을 다시 디자인하고 그대로 둡니다.RecyclerView하드코드를 하는 것보다 더 나은 해결책이 될 것입니다.

또한 오버라이드할 수 있습니다.LinearLayoutManager만들기 위해서RecyclerView부드럽게 롤링:

@Override
public boolean canScrollVertically(){
    return false;
}

나에게 효과가 있는 솔루션

사용하다NestedScrollView가 키가인wrap_content그리고 당신을 위해RecyclerView설정:

<androidx.recyclerview.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:nestedScrollingEnabled="false"
    app:layoutManager="android.support.v7.widget.LinearLayoutManager" />

그리고 뷰 홀더 레이아웃 파라미터를 설정합니다.

android:layout_width="match_parent"
android:layout_height="wrap_content"

언급URL : https://stackoverflow.com/questions/27083091/recyclerview-inside-scrollview-is-not-working

반응형