에서 스크롤을 사용 중지 할 수 없습니다 RecyclerView
. 전화를 시도 rv.setEnabled(false)
했지만 여전히 스크롤 할 수 있습니다.
스크롤을 비활성화하려면 어떻게해야합니까?
View
위에 투명하게 놓았을 수도 있고 필요에 따라 RecyclerView
토글 할 수도 있지만 커프를 벗으면 접근이 합리적입니다. VISIBLE
GONE
에서 스크롤을 사용 중지 할 수 없습니다 RecyclerView
. 전화를 시도 rv.setEnabled(false)
했지만 여전히 스크롤 할 수 있습니다.
스크롤을 비활성화하려면 어떻게해야합니까?
View
위에 투명하게 놓았을 수도 있고 필요에 따라 RecyclerView
토글 할 수도 있지만 커프를 벗으면 접근이 합리적입니다. VISIBLE
GONE
답변:
이를 위해 recycleview의 레이아웃 관리자를 재정의해야합니다. 이렇게하면 스크롤 기능 만 비활성화되고 다른 기능은 없습니다. 클릭 또는 기타 터치 이벤트를 계속 처리 할 수 있습니다. 예를 들면 다음과 같습니다.
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;
}
};
NestedScrollView
: android.support.v4.widget.NestedScrollView
, chessdork에 의해 여기에서 설명한대로 : stackoverflow.com/questions/37846245/...
실제 답변은 다음과 같습니다. 과 같습니다. API 21 이상 :
자바 코드가 필요하지 않습니다. android:nestedScrollingEnabled="false"
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">
이것은 약간의 hackish 해결 방법이지만 작동합니다. 에서 스크롤을 활성화 / 비활성화 할 수 있습니다.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;
}
});
Custom view 'RecyclerView' has setOnTouchListener called on it but does not override performClick
return e.getAction() == MotionEvent.ACTION_MOVE;
않고 모든 종류의 터치 이벤트를 비활성화하는 대신 return true;
스크롤 / 스 와이프 이벤트 만 취소됩니다.
RecyclerView를 고정하여 스크롤을 비활성화 할 수 있습니다.
얼리려면 :
recyclerView.setLayoutFrozen(true)
고정을 해제하려면 recyclerView.setLayoutFrozen(false)
확장 클래스 만들기 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);
recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
// Stop only scrolling.
return rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING;
}
});
또 다른 대안은 setLayoutFrozen
이지만 다른 부작용도 있습니다.
코 틀린 버전 작성 :
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()
을 확장 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) {
}
});
XML에서 :-
추가 할 수 있습니다
android:nestedScrollingEnabled="false"
자식 RecyclerView 레이아웃 XML 파일에서
또는
자바에서 :-
childRecyclerView.setNestedScrollingEnabled(false);
Java 코드로 RecyclerView에.
ViewCompat (Java) 사용 :-
childRecyclerView.setNestedScrollingEnabled(false);
android_version> 21 기기 에서만 작동 합니다. 모든 장치에서 작동하려면 다음을 사용하십시오.
ViewCompat.setNestedScrollingEnabled(childRecyclerView, false);
어떤 이유로 @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) {
}
});
onTouchEvent () 및 onInterceptTouchEvent ()를 재정의하고 OnItemTouchListener가 전혀 필요하지 않으면 false를 반환합니다. ViewHolders의 OnClickListener를 비활성화하지 않습니다.
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;
}
}
한 시간 동안이 문제에 어려움을 겪고 있으므로 경험을 공유하고 싶습니다. layoutManager 솔루션의 경우 문제가 없지만 스크롤을 다시 활성화하려면 재활용기를 맨 위로 올리십시오.
지금까지 가장 좋은 해결책은 @Zsolt Safrany 메소드를 사용하는 것이지만 getter 및 setter를 추가하여 OnItemTouchListener를 제거하거나 추가 할 필요가 없습니다.
다음과 같이
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);
다음은 데이터 바인딩으로 수행 한 방법입니다.
<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에서 하나의 스크롤 막대 대신 하나의 스크롤 막대 만 필요합니다.
그래서 2 개의 RecycleView가 들어있는 상위 컨테이너에 ScrollView를 넣고 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" />
더하다
android:descendantFocusability="blocksDescendants"
SrollView 또는 NestedScrollView의 자녀 (및 ListView의 부모, recyclerview 및 gridview 중 하나)
표준 기능 만 사용하여 스크롤링을 비활성화하는보다 직접적인 방법이 있습니다 (기술적으로는 스크롤링 이벤트를 가로 채서 조건이 충족되면 종료하는 것입니다). 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
stopScroll()
스크롤을 멈추는 것이 아니라 스크롤 리사이클 뷰를 중지 / 중지하는 것입니다.
isItemSelected
설정하여 RecyclerView 컨텐츠를 스크롤하려고 할 때마다 수행됩니다 true
. 그렇지 않으면 스크롤을 비활성화하기 위해 사용자 정의 RecyclerView가 필요 하며이 솔루션이 제공하는 약간의 추가 기능이 필요하기 때문에 피하기를 원했습니다.
터치하여 스크롤을 중지하지만 명령을 통해 계속 스크롤하려면 :
if (appTopBarMessagesRV == null) {appTopBarMessagesRV = findViewById (R.id.mainBarScrollMessagesRV);
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;
}
});
}
RecyclerView
스크롤을 원하지 않는 경우 사용 요점은 무엇입니까 ?