sourcecode

RecyclerView 스크롤을 비활성화하는 방법은 무엇입니까?

copyscript 2023. 7. 28. 22:32
반응형

RecyclerView 스크롤을 비활성화하는 방법은 무엇입니까?

에서 스크롤을 비활성화할 수 없습니다.RecyclerView는 봤다습니전에 해 보았습니다.rv.setEnabled(false)그래도 스크롤은 할 수 있어요

스크롤을 비활성화하려면 어떻게 해야 합니까?

를 덮어써야 합니다.layoutManager의 신의의recycleView할 수 .이렇게 하면 스크롤만 비활성화되고 다른 기능은 비활성화됩니다.클릭 또는 기타 터치 이벤트는 계속 처리할 수 있습니다. -sys:-

원본:

public class CustomGridLayoutManager extends LinearLayoutManager {
    private boolean isScrollEnabled = true;

    public CustomGridLayoutManager(Context context) {
        super(context);
    }

    public void setScrollEnabled(boolean flag) {
        this.isScrollEnabled = flag;
    }

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

여기서 "isScrollEnabled" 플래그를 사용하여 재활용 보기의 스크롤 기능을 일시적으로 활성화/비활성화할 수 있습니다.

또한:

기존 구현을 재정의하여 스크롤을 사용하지 않도록 설정하고 클릭을 허용합니다.

linearLayoutManager = new LinearLayoutManager(context) {
    @Override
    public boolean canScrollVertically() {
        return false;
    }
};

코틀린에서:

object : LinearLayoutManager(this) { override fun canScrollVertically() = false }

진짜 답은

recyclerView.setNestedScrollingEnabled(false);

설명서의 추가 정보

API 21 이상의 경우:

Java 코드가 필요하지 않습니다.설정할 수 있습니다.android:nestedScrollingEnabled="false"xml:xml 파일:

<android.support.v7.widget.RecyclerView
     android:id="@+id/recycler"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:clipToPadding="true"
     android:nestedScrollingEnabled="false"
     tools:listitem="@layout/adapter_favorite_place">

해크적인 ; 할 수 . 당신은 에서 스크롤을 활성화/비활성화할 수 있습니다.RecyclerView.

이것은 비어 있습니다.RecyclerView.OnItemTouchListener RecyclerView.

public class RecyclerViewDisabler implements RecyclerView.OnItemTouchListener {

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        return true;
    }

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

    }

    @Override
    public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
}

사용:

RecyclerView rv = ...
RecyclerView.OnItemTouchListener disabler = new RecyclerViewDisabler();

rv.addOnItemTouchListener(disabler);        // disables scolling
// do stuff while scrolling is disabled
rv.removeOnItemTouchListener(disabler);     // scrolling is enabled again 

이것은 나에게 도움이 됩니다.

  recyclerView.setOnTouchListener(new View.OnTouchListener() {
      @Override
      public boolean onTouch(View v, MotionEvent event) {
          return true;
      }
  });

~하듯이setLayoutFrozen더 이상 사용되지 . 를 할 수 . 다음을 사용하여 RecyclerView를 동결하여 스크롤을 비활성화할 수 있습니다.suppressLayout.

고정 방법:

recyclerView.suppressLayout(true)

고정 해제 방법:

recyclerView.suppressLayout(false)
recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
        @Override
        public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
            // Stop only scrolling.
            return rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING;
        }
    });

RecyclerView를 중지하여 스크롤을 비활성화할 수 있습니다.

고정방법:recyclerView.setLayoutFrozen(true)

해제하기: 고정해방법:recyclerView.setLayoutFrozen(false)

간단한 답이 있습니다.

LinearLayoutManager lm = new LinearLayoutManager(getContext()) {
                @Override
                public boolean canScrollVertically() {
                    return false;
                }
            };

위의 코드는 RecyclerView의 세로 스크롤을 비활성화합니다.

RecyclerView 클래스를 확장하는 클래스 만들기

public class NonScrollRecyclerView extends RecyclerView {

    public NonScrollRecyclerView(Context context) {
        super(context);
    }

    public NonScrollRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public NonScrollRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(
                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
        ViewGroup.LayoutParams params = getLayoutParams();
        params.height = getMeasuredHeight();
    }
}

스크롤 이벤트는 비활성화되지만 클릭 이벤트는 비활성화되지 않습니다.

XML에서 이를 사용하여 다음 작업을 수행합니다.

  <com.yourpackage.xyx.NonScrollRecyclerView 
     ...
     ... 
  />

스크롤 기능만 비활성화하는 경우RecyclerView그러면 사용할 수 있습니다.setLayoutFrozen(true);RecyclerView그러나 터치 이벤트를 비활성화할 수는 없습니다.

your_recyclerView.setLayoutFrozen(true);

Kotlin에서 하나의 값만 설정하기 위해 추가 클래스를 만들지 않으려면 LayoutManager에서 익명 클래스를 만들 수 있습니다.

recyclerView.layoutManager = object : LinearLayoutManager(context) {
    override fun canScrollVertically(): Boolean = false
}

코틀린 버전 작성:

class NoScrollLinearLayoutManager(context: Context?) : LinearLayoutManager(context) {
    private var scrollable = true

    fun enableScrolling() {
        scrollable = true
    }

    fun disableScrolling() {
        scrollable = false
    }

    override fun canScrollVertically() =
            super.canScrollVertically() && scrollable


    override fun canScrollHorizontally() =
            super.canScrollVertically()

 && scrollable
}

용도:

recyclerView.layoutManager = NoScrollLinearLayoutManager(context)
(recyclerView.layoutManager as NoScrollLinearLayoutManager).disableScrolling()

XML에서 :-

추가할 수 있습니다.

android:nestedScrollingEnabled="false"

하위 RecyclerView 레이아웃 XML 파일에서

또는

Java에서 :-

childRecyclerView.setNestedScrollingEnabled(false);

Java 코드의 RecyclerView로 이동합니다.

ViewCompat(Java) 사용하기:-

childRecyclerView.setNestedScrollingEnabled(false);Android_version>21개의 장치에서만 작동합니다.모든 장치에서 작동하려면 다음을 사용합니다.

ViewCompat.setNestedScrollingEnabled(childRecyclerView, false);

다른 은 또다대안은입니다.setLayoutFrozen다른 부작용도 많이 있습니다

https://developer.android.com/reference/android/support/v7/widget/RecyclerView.html#setLayoutFrozen(boolean)

확장기를 합니다.LayoutManager 및오라드이버드를 재정의합니다.canScrollHorizontally()그리고.canScrollVertically()스크롤을 비활성화합니다.

처음에 항목을 삽입하면 자동으로 처음으로 스크롤되지 않으므로 다음과 같은 작업을 수행합니다.

  private void clampRecyclerViewScroll(final RecyclerView recyclerView)
  {
    recyclerView.getAdapter().registerAdapterDataObserver(new RecyclerView.AdapterDataObserver()
    {
      @Override
      public void onItemRangeInserted(int positionStart, int itemCount)
      {
        super.onItemRangeInserted(positionStart, itemCount);
        // maintain scroll position at top
        if (positionStart == 0)
        {
          RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
          if (layoutManager instanceof GridLayoutManager)
          {
            ((GridLayoutManager) layoutManager).scrollToPositionWithOffset(0, 0);
          }else if(layoutManager instanceof LinearLayoutManager)
          {
            ((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(0, 0);
          }
        }
      }
    });
  }

이미 승인된 답변이 있는 것은 알지만, 솔루션은 제가 발견한 사용 사례를 고려하지 않습니다.

저는 특히 클릭할 수 있으면서도 RecyclerView의 스크롤 메커니즘을 비활성화하는 헤더 항목이 필요했습니다.이 작업은 다음 코드로 수행할 수 있습니다.

recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
                            @Override
     public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
         return e.getAction() == MotionEvent.ACTION_MOVE;
     }

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

     }

     @Override
     public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {

    }
});

@Alejandro Gracia는 어떤 이유에서인지 몇 초 후에야 대답이 작동하기 시작합니다.RecyclerView를 즉시 차단하는 솔루션을 찾았습니다.

recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
                return true;
            }
            @Override
            public void onTouchEvent(RecyclerView rv, MotionEvent e) {
            }
            @Override
            public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
            }
        });

터치 이벤트() 및 인터셉트 시 재정의OnItem이 필요 없는 경우 Event()를 누르고 false를 반환합니다.청취자를 터치합니다.이렇게 해도 OnClickListeners of View는 비활성화되지 않습니다.홀더들.

public class ScrollDisabledRecyclerView extends RecyclerView {
    public ScrollDisabledRecyclerView(Context context) {
        super(context);
    }

    public ScrollDisabledRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ScrollDisabledRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        return false;
    }
}

이것을 xml의 재활용 보기에 추가하기만 하면 됩니다.

 android:nestedScrollingEnabled="false"

이것처럼.

<android.support.v7.widget.RecyclerView
                    android:background="#ffffff"
                    android:id="@+id/myrecycle"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:nestedScrollingEnabled="false">

더하다

android:descendantFocusability="blocksDescendants"

SrollView 또는 NestedScrollView의 하위 항목(및 ListView, 재활용자 뷰 및 그리드 뷰의 상위 항목)

다음 행만 추가하면 됩니다.

recyclerView.suppressLayout(true)

몇 시간 동안 이 문제로 어려움을 겪었기 때문에 layoutManager 솔루션의 경우 괜찮지만 다시 스크롤을 활성화하려면 재활용업체가 다시 정상으로 돌아갑니다.

지금까지 (적어도 나에게는) 가장 좋은 솔루션은 @Zsolt Safrany 방법을 사용하는 것이지만 온아이템을 제거하거나 추가할 필요가 없도록 게터와 세터를 추가하는 것입니다.청취자를 누릅니다.

다음과 같이

public class RecyclerViewDisabler implements RecyclerView.OnItemTouchListener {

    boolean isEnable = true;

    public RecyclerViewDisabler(boolean isEnable) {
        this.isEnable = isEnable;
    }

    public boolean isEnable() {
        return isEnable;
    }

    public void setEnable(boolean enable) {
        isEnable = enable;
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
        return !isEnable;
    }

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

   @Override
   public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept){}
 }

사용.

RecyclerViewDisabler disabler = new RecyclerViewDisabler(true);
feedsRecycler.addOnItemTouchListener(disabler);

// TO ENABLE/DISABLE JUST USE THIS
disabler.setEnable(enable);

어댑터를 설정한 후 이 라인을 추가할 수 있습니다.

ViewCompat.setNestedScrollingEnabled(recyclerView, false);

이제 재활용품 보기가 부드러운 스크롤로 작동합니다.

표준 기능을 사용하여 스크롤을 비활성화하는 보다 간단한 방법이 있습니다(기술적으로는 스크롤 이벤트를 차단하고 조건이 충족되면 이벤트를 종료하는 것이 좋습니다).RecyclerView에는 라하는방있습니다법이고라는 .addOnScrollListener(OnScrollListener listener)이것만 사용하면 스크롤을 중지할 수 있습니다.

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);
        if (viewModel.isItemSelected) {
            recyclerView.stopScroll();
        }
    }
});

사용 사례:예를 들어 다음 중 하나의 항목을 클릭할 때 스크롤을 사용하지 않도록 설정할 수 있습니다.RecyclerView따라서 실수로 다른 항목으로 스크롤하는 데 방해받지 않고 해당 항목을 몇 가지 작업을 수행할 수 있으며, 작업이 완료되면 해당 항목을 다시 클릭하여 스크롤을 활성화할 수 있습니다.이를 위해, 당신은 첨부하고 싶을 것입니다.OnClickListener내의 모든 항목에RecyclerView그래서 항목을 클릭하면 항목이 전환됩니다.isItemSelected부터false로.true이렇게 스크롤을 하려고 하면,RecyclerView자동으로 메서드를 호출합니다.onScrollStateChanged그 이후로isItemSelected로 설정한.true그것은 즉시 멈출 것입니다, 전에.RecyclerView기회가 있어요, 음...스크롤합니다.

참고: 더 나은 사용 편의성을 위해 다음을 사용해 보십시오.GestureListener대신에OnClickListener예방하기 위해accidental딸깍하는 소리

누가 사용자가 사용자가 사용자 보기를 자유롭게 스크롤하는 것을 방지하기를 원합니까?smoothScrollToPosition또는 다른 "위치로 이동" 방법, 나는 오히려 확장하는 것을 추천합니다.RecyclerView 스클래, 의정재를 onTouchEvent다음과 같이:

            public class HardwareButtonsRecyclerView extends RecyclerView {
            
                    public HardwareButtonsRecyclerView(@NonNull Context context) {
                        super(context);
                    }
            
                    public HardwareButtonsRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
                        super(context, attrs);
                    }
            
                    public HardwareButtonsRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
                        super(context, attrs, defStyleAttr);
                    }
            
                @Override
                public boolean onTouchEvent(MotionEvent e) {
                    return false;
                }
            }

Activity's onCreate 메서드에서 다음 작업을 간단히 수행할 수 있습니다.

recyclerView.stopScroll()

화면 이동이 멈춥니다.

데이터 바인딩을 사용한 방법은 다음과 같습니다.

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:clipChildren="false"
                android:onTouch="@{(v,e) -> true}"/>

"true" 대신 조건에 따라 변경된 부울 변수를 사용하여 재사용자 보기가 사용 안 함과 사용 안 함으로 전환되도록 했습니다.

여러 개의 RecycleView가 포함된 조각이 발견되었으므로 각 RecycleView에 스크롤바 하나가 아니라 스크롤바 하나만 있으면 됩니다.

그래서 ScrollView를 2개의 RecycleView가 들어 있는 상위 컨테이너에 넣고 사용했습니다.android:isScrollContainer="false"에서 확인할 수 .

<android.support.v7.widget.RecyclerView 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:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutManager="LinearLayoutManager"
    android:isScrollContainer="false" />

터치를 통해 스크롤을 중지하고 명령을 통해 스크롤을 계속하려면 다음과 같이 하십시오.

if (app TopBar 메시지)RV == null) {appTopBarMessagesRV = findViewById(R.id .mainBarScrollMessages)RV);

        appTopBarMessagesRV.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
            @Override
            public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {

                if ( rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING)
                {
                     // Stop  scrolling by touch

                    return false;
                }
                return  true;
            }
        });
    }

언급URL : https://stackoverflow.com/questions/30531091/how-to-disable-recyclerview-scrolling

반응형