RecyclerView 스크롤을 비활성화하는 방법은 무엇입니까?
에서 스크롤을 사용 중지 할 수 없습니다 RecyclerView. 전화를 시도 rv.setEnabled(false)했지만 여전히 스크롤 할 수 있습니다.
스크롤을 비활성화하려면 어떻게해야합니까?
이를 위해 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;
}
};
진정한 대답은
recyclerView.setNestedScrollingEnabled(false);
설명서의 추가 정보
REAL REAL 답변은 다음 과 같습니다. 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;
}
});
RecyclerView를 고정하여 스크롤을 비활성화 할 수 있습니다.
얼리려면 : recyclerView.setLayoutFrozen(true)
고정을 해제하려면 recyclerView.setLayoutFrozen(false)
그냥 비활성화하는 경우 에만 스크롤 기능 의 RecyclerView다음 사용할 수있는 setLayoutFrozen(true);방법을 RecyclerView. 그러나 터치 이벤트를 비활성화 할 수 없습니다.
your_recyclerView.setLayoutFrozen(true);
확장 클래스 만들기 RecyclerView의 클래스
public class NonscrollRecylerview extends RecyclerView {
public NonscrollRecylerview(Context context) {
super(context);
}
public NonscrollRecylerview(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public NonscrollRecylerview(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.NonscrollRecylerview
...
...
/>
또 다른 대안은 setLayoutFrozen이지만 여러 가지 다른 부작용이 있습니다.
recyclerView.addOnItemTouchListener(new RecyclerView.SimpleOnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
// Stop only scrolling.
return rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING;
}
});
을 확장 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);
}
}
}
});
}
코 틀린 버전 작성 :
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()
나는 이것이 이미 받아 들여진 대답을 알고 있지만 해결책은 내가 찾은 유스 케이스를 고려하지 않습니다.
나는 여전히 클릭 가능한 헤더 항목이 필요했지만 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) {
}
});
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;
}
}
어댑터를 설정 한 후이 줄을 추가 할 수 있습니다
ViewCompat.setNestedScrollingEnabled(recyclerView, false);
이제 recyclerview는 부드러운 스크롤로 작동합니다.
정말 간단한 대답이 있습니다.
LinearLayoutManager lm = new LinearLayoutManager(getContext()) {
@Override
public boolean canScrollVertically() {
return false;
}
};
위의 코드는 RecyclerView를 세로로 스크롤하지 못하게합니다.
한 시간 동안이 문제에 어려움을 겪고 있으므로 경험을 공유하고 싶습니다. 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);
XML에서 :-
추가 할 수 있습니다
android:nestedScrollingEnabled="false"
자식 RecyclerView 레이아웃 XML 파일에서
또는
자바에서 :-
childRecyclerView.setNestedScrollingEnabled(false);
Java 코드로 RecyclerView에.
Using ViewCompat (Java) :-
childRecyclerView.setNestedScrollingEnabled(false); will work only in android_version>21 devices. to work in all devices use the following
ViewCompat.setNestedScrollingEnabled(childRecyclerView, false);
Here is how I did it with data binding:
<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}"/>
In place of the "true" I used a boolean variable that changed based on a condition so that the recycler view would switch between being disabled and enabled.
Came across with a fragment that contains multiple RecycleView so I only need one scrollbar instead of one scrollbar in each RecycleView.
So I just put the ScrollView in the parent container that contains the 2 RecycleViews and use android:isScrollContainer="false" in the RecycleView
<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" />
Add
android:descendantFocusability="blocksDescendants"
in your child of SrollView or NestedScrollView (and parent of ListView, recyclerview and gridview any one)
There is a more straightforward way to disable scrolling (technically it is more rather interception of a scrolling event and ending it when a condition is met), using just standard functionality. RecyclerView has the method called addOnScrollListener(OnScrollListener listener), and using just this you can stop it from scrolling, just so:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (viewModel.isItemSelected) {
recyclerView.stopScroll();
}
}
});
Use case: Let's say that you want to disable scrolling when you click on one of the items within RecyclerView so you could perform some actions with it, without being distracted by accidentally scrolling to another item, and when you are done with it, just click on the item again to enable scrolling. For that, you would want to attach OnClickListener to every item within RecyclerView, so when you click on an item, it would toggle isItemSelected from false to true. This way when you try to scroll, RecyclerView will automatically call method onScrollStateChanged and since isItemSelected set to true, it will stop immediately, before RecyclerView got the chance, well... to scroll.
Note: for better usability, try to use GestureListener instead of OnClickListener to prevent accidental clicks.
Just add this to your recycleview in xml
android:nestedScrollingEnabled="false"
like this
<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">
참고URL : https://stackoverflow.com/questions/30531091/how-to-disable-recyclerview-scrolling
'IT' 카테고리의 다른 글
| 지시어 정의의 transclude 옵션을 이해하고 있습니까? (0) | 2020.05.14 |
|---|---|
| 문서에 대한 문법 제한 조건 (DTD 또는 XML 스키마)이 발견되지 않았습니다. (0) | 2020.05.14 |
| 일치하는 값이 포함 된 해시 키를 찾는 방법 (0) | 2020.05.14 |
| 오류가 발생하면 자동으로 파이썬 디버거 시작 (0) | 2020.05.14 |
| 자바 스크립트 스왑 배열 요소 (0) | 2020.05.14 |