ViewPager에서 손가락으로 스 와이프하여 페이징을 비활성화하지만 프로그래밍 방식으로 계속 스 와이프하는 방법은 무엇입니까?


549

ViewPager가 있고 그 아래에는 10 개의 버튼이 있습니다. 버튼 (예 : # 4)을 클릭하면 호출기는 by by 페이지 # 4로 즉시 이동합니다 mPager.setCurrentItem(3);. 그러나 손가락으로 가로로 스 와이프하여 페이징을 비활성화하고 싶습니다. 따라서 페이징은 버튼을 클릭 해야만 수행됩니다 . 그렇다면 손가락으로 스 와이프를 비활성화하는 방법은 무엇입니까?


처음에 ViewFlipper 를 사용하는 것은 어떻습니까? 그것은 당신에게 많은 두통을 저장합니다.
— Alex Semeniuk

답변:


885

서브 클래 싱해야합니다 ViewPager. onTouchEvent아이 뷰를 터치하는 것과 같이 변경하고 싶지 않은 좋은 것들이 많이 있습니다. onInterceptTouchEvent당신이 바꾸고 싶은 것입니다. 의 코드를 보면 ViewPager주석이 표시됩니다.

    /*
     * This method JUST determines whether we want to intercept the motion.
     * If we return true, onMotionEvent will be called and we do the actual
     * scrolling there.
     */

완벽한 솔루션은 다음과 같습니다.

먼저이 클래스를 src폴더에 추가하십시오 .

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.animation.DecelerateInterpolator;
import android.widget.Scroller;
import java.lang.reflect.Field;

public class NonSwipeableViewPager extends ViewPager {

    public NonSwipeableViewPager(Context context) {
        super(context);
        setMyScroller();
    }

    public NonSwipeableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        setMyScroller();
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages
        return false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Never allow swiping to switch between pages
        return false;
    }

    //down one is added for smooth scrolling

    private void setMyScroller() {
        try {
            Class<?> viewpager = ViewPager.class;
            Field scroller = viewpager.getDeclaredField("mScroller");
            scroller.setAccessible(true);
            scroller.set(this, new MyScroller(getContext()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public class MyScroller extends Scroller {
        public MyScroller(Context context) {
            super(context, new DecelerateInterpolator());
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            super.startScroll(startX, startY, dx, dy, 350 /*1 secs*/);
        }
    }
}

다음으로, 일반 대신이 클래스를 사용할 수 있는지 확인하십시오 ViewPager당신은 아마로 지정하는 android.support.v4.view.ViewPager. 레이아웃 파일에서 다음과 같이 지정하십시오.

<com.yourcompany.NonSwipeableViewPager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" />

이 특정 예는 a에 LinearLayout있고 전체 화면을 차지하기위한 것이므로 layout_weight1 layout_height은 0dp입니다.

그리고 setMyScroller();부드러운 전환을위한 방법입니다


3
@louielouie 참고 사항 : 왜 특별한 이유가 있습니까? 왜 전체 화면 효과를 얻기 위해 높이 보다 높이 0dp/ 1무게 솔루션 을 선택 match_parent했습니까? 그렇게하면 성능이 향상됩니까?
— ubuntudroid

28
이 답변은 키보드의 왼쪽 / 오른쪽 키를 사용할 때 페이지 스 와이프를 방지하지 않습니다 (에뮬레이터에서 시도). 터치 장치에는 문제가되지 않지만 TV 및 랩톱에서는 문제가 될 수 있습니다.
— Vincent Mimoun-Prat

8
@MarvinLabs @Thorbear 키보드로 페이지 스크롤을 비활성화하는 올바른 방법은을 재정의하는 것 executeKeyEvent()입니다. 그런 다음이 메소드를 호출 allowScroll()합니다. // Never allow swiping by keyboard LEFT, RIGHT, TAB and SHIFT+TAB keys @Override public boolean executeKeyEvent(KeyEvent event) { return false; }
— araks

6
글쎄, 이것은 세로 스크롤도 비활성화합니다 ... 목록보기를 사용하는 경우 이것은 좋지 않습니다.
— maysi

5
Google이 터치 / 스 와이프 처리 방법에 대한 인터페이스 방법을 제공하는 방법을 제공했을 수 있기를 바랍니다.
— Neon Warge

466

보다 일반적인 확장은 즉시 페이징을 활성화 및 비활성화 할 수 ViewPager있는 SetPagingEnabled방법 을 만드는 것 입니다. 활성화 / 스 와이프, 단지 오버라이드 (override)하는 두 가지 방법을 사용하지 않으려면 : onTouchEvent와 onInterceptTouchEvent. 페이징이 비활성화 된 경우 둘 다 "false"를 반환합니다.

public class CustomViewPager extends ViewPager {

    private boolean enabled;

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.enabled = true;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (this.enabled) {
            return super.onTouchEvent(event);
        }

        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        if (this.enabled) {
            return super.onInterceptTouchEvent(event);
        }

        return false;
    }

    public void setPagingEnabled(boolean enabled) {
        this.enabled = enabled;
    } 
}

그런 다음 XML의 내장 viewpager 대신 이것을 선택하십시오.

<mypackage.CustomViewPager 
    android:id="@+id/myViewPager" 
    android:layout_height="match_parent" 
    android:layout_width="match_parent" />

setPagingEnabled메소드 를 호출하기 만하면 false사용자가 스 와이프하여 페이지 매김을 할 수 없습니다.


3
가로 스크롤을 사용하는 여러 하위보기가있는보기 (예 : AChartEngine 차트)에 완벽하게 작동합니다. 내 조각에서 사용자가 차트를 터치했는지 (ACTION_MOVE) 또는 떠 났는지 (ACTION_CANCEL) 여부에 따라 페이징을 켜거나 끄라고 말하는 내 활동에 대한 콜백을 사용합니다. 고마워요!
— 익는

32
당신은 당신의 단순화 onTouchEvent와 onInterceptTouchEvent함께 방법을return enabled && super.onTouchEvent(event);
— nbarraille

2
@nbarraille 스타일의 문제 일뿐입니다. 더 읽기 쉬운 스타일을 사용할 수 있습니다.
— Rajul

7
또한 필드 이름을 "enabled"에서 "swipePageChangeEnabled"또는 이와 유사한 것으로 변경하는 것이 좋습니다. 코드를 작성하고 한 달 후, "클래스가"CustomViewPager "라고하는 경우"활성화 됨 "의 의미를 거의 기억하지 못할 것입니다. 여기서는 사용자 정의가 무엇인지 명확하지 않습니다. 그것은 또한 스타일의 문제이지만, 지원 할 수없는 프로젝트로 끝내고 싶지 않다면 스타일이 중요합니다. 그것은 수정하는 것보다 완전히 다시 쓰는 것이 더 쉽습니다.
— bytefu

3
setPagingEnabled는 어디에서 호출합니까? ._.
— Ntikki

107

가장 간단한 방법은로 setOnTouchListener돌아가는 것 true입니다 ViewPager.

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

53
때때로 작동하지 않습니다. FragmentPagerAdapter 및 여러 Fragment와 함께 ViewPager를 사용하고 있습니다. OnTouchListener를 호출기로 설정 한 후 왼쪽으로 날아가도 UI는 여전히 약간 왼쪽으로 이동합니다.
— Chris.Zou

16
pager.setCurrentItem(pager.getCurrentItem());반환하기 전에 추가 할 때 작동합니다 true.
— dng

1
그것은 전에 나를 위해 일했다. 왜 더 이상 잘 작동하지 않는지 모르겠습니다.
— 안드로이드 개발자

나를 위해 일하는 것 같습니다. public int getItemPosition(Object object) { return POSITION_NONE; }어댑터에있는 레이아웃 결함을 해결하려면 페이지를 강제로 재생하고 다른 문제도 해결할 수 있습니다.
— r-hold

6
이것은 부분적으로 작동하는 솔루션입니다. 가로 스 와이프는 이상한 방식으로 처리됩니다. ViewPager의 일부로 Drag'n Drop Gridview로 이것을 테스트했습니다. 이 솔루션을 사용하여 끌면 왼쪽에서 오른쪽으로, 오른쪽에서 왼쪽으로 끌지 못합니다. 개인적으로 나는 Rajul의 접근 방식이 가장 좋습니다.
— Ton Snoei

58

스타일을 선언하는 것이 좋으므로 xml에서 속성을 변경할 수 있습니다.

private boolean swipeable;

public MyViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyViewPager);
    try {
        swipeable = a.getBoolean(R.styleable.MyViewPager_swipeable, true);
    } finally {
        a.recycle();
    }
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    return swipeable ? super.onInterceptTouchEvent(event) : false;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    return swipeable ? super.onTouchEvent(event) : false;
}

그리고 values ​​/ attr.xml에서 :

<declare-styleable name="MyViewPager">
  <attr name="swipeable" format="boolean" />
</declare-styleable>

레이아웃 xml에서 사용할 수 있도록 :

<mypackage.MyViewPager
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/viewPager"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:swipeable="false" />

물론 get / set 속성을 계속 가질 수 있습니다.


58

다른 ViewPager 내에 ViewPager 자체가있는 경우 에만 재정의 onTouchEvent하고 onInterceptTouchEvent충분하지 않습니다. Child ViewPager는 첫 번째 / 마지막 페이지에 위치하지 않는 한 상위 ViewPager에서 가로 스크롤 터치 이벤트를 훔칩니다.

이 설정이 제대로 작동하려면 canScrollHorizontally방법 도 재정의해야합니다 .

아래 LockableViewPager구현을 참조하십시오 .

public class LockableViewPager extends ViewPager {

    private boolean swipeLocked;

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

    public LockableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public boolean getSwipeLocked() {
        return swipeLocked;
    }

    public void setSwipeLocked(boolean swipeLocked) {
        this.swipeLocked = swipeLocked;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return !swipeLocked && super.onTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return !swipeLocked && super.onInterceptTouchEvent(event);
    }

    @Override
    public boolean canScrollHorizontally(int direction) {
        return !swipeLocked && super.canScrollHorizontally(direction);
    }

}

3
감사합니다. 다른 ViewPager의 ViewPager에서 매우 잘 작동합니다.
— Fernanda Bari

1
이것은 다른 ViewPager 내부의 ViewPager에서도 작동합니다. 이 경우 올바른 솔루션이 작동하지 않았습니다.
— Rafael Ruiz Muñoz

탭에서 사용될 때 애니메이션도 멈 춥니 다.
— Rishabh Srivastava 2016 년

비활성화하고 활성화하고 싶다면 setSwipeLocked (false)를 호출하는 이벤트를 얻을 수있는 곳은 어디입니까?
— Ravi Yadav 2016 년

57

이제 우리는 사용자 정의를 만들 필요가 없습니다 ViewPager

ViewPager2 안드로이드에서 사용 가능한 새로운 이름보기

수직 방향 지원

  • ViewPager2전통적인 수평 페이징 외에 수직 페이징을 지원합니다. ViewPager2요소의 android:orientation속성 을 설정 하여 요소에 대한 수직 페이징을 활성화 할 수 있습니다

XML 사용

<androidx.viewpager2.widget.ViewPager2
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:orientation="vertical" />

코드 사용

에서 비활성화 스 와이프로 viewpager2사용

viewPager2.setUserInputEnabled(false);

사용중인 스 와이프를 활성화 viewpager2하려면

viewPager2.setUserInputEnabled(true);

자세한 내용은 이것을 확인하십시오

최신 정보


3
훌륭하지만 여전히 불완전한 것처럼 보입니다. 나는 5 개 가지 조각으로와 페이지 사이를 전환 한 후 그것을 시도했습니다 파편 중 하나가 가지였다 손실, 즉보기는 어느 쪽도 복원되지되지 않으며 재 - 팽창
— Toochka

@Toochka 죄송합니다. 잘 작동하고 있습니다. 여기에서 샘플 작업 코드를 찾을 수 있습니다. stackoverflow.com/a/54643817/7666442 가능한 경우 코드를 공유하십시오
— Nilesh Rathod

1
이 방법을 사용하여 ViewPager2에서 스 와이프를 성공적으로 비활성화 할 수 있습니다
— voghDev

1
그 듣고 @voghDev 행복
— Nilesh Rathod

1
@PhaniRithvij이 응답 확인하시기 바랍니다 stackoverflow.com/a/54643817/7666442을 내가 어떻게 사용하는 모든 세부 사항을 추가 viewpager2로RecyclerView.Adapter
— Nilesh Rathod

35

ViewPager에서 확장하는 경우 이전에 @araks로 표시된대로 재정의해야합니다.executeKeyEvent

@Override
public boolean executeKeyEvent(KeyEvent event)
{
    return isPagingEnabled ? super.executeKeyEvent(event) : false;
}

Galaxy Tab 4 10 '과 같은 일부 장치는 대부분의 장치가 표시하지 않는 다음 단추를 표시합니다.

키보드 버튼


50
삼성은 항상 안드로이드 개발자를 위해 일을 망치고 있습니다.
— toobsco42

2
@ toobsco42이 경우 삼성은 혼자가 아닙니다. SwiftKey (인기 키보드 앱)를 사용하면 키보드에 화살표를 넣을 수 있습니다.
— 수피

1
키보드 / 트래커 볼을 사용하는 사람이 호출기를 호출하지 못하게하려면이 방법도 수정되었습니다.
— se22as

28

스 와이프를 비활성화하려면

mViewPager.beginFakeDrag();

스 와이프를 사용하려면

mViewPager.endFakeDrag();

22
적어도 내 앱에서 작은 부분의 움직임을 허용하기 때문에 좋은 해결책이 아닙니다.
— koras

나를 위해 잘 작동합니다. 제공된 다른 솔루션과 비교하여 단점은 무엇입니까?
— userM1433372

13

특정 페이지에서 스 와이프를 비활성화하고 멋진 고무 밴드 애니메이션을 제공해야했습니다. 방법은 다음과 같습니다.

    mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageScrolled(int position, float positionOffset,
                                   int positionOffsetPixels) {
            if (position == MANDATORY_PAGE_LOCATION && positionOffset > 0.5) {
                mViewPager.setCurrentItem(MANDATORY_PAGE_LOCATION, true);
            }
        }

다음 페이지가 부분적으로 표시 될 때까지 기다립니다. 다음 페이지의 코드 onPageSelected가 실행됩니다. 다음 페이지에서도 전환됩니다. 따라서이 코드는 필요하지 않습니다.
— CoolMind

13

나는 이것을 게시하는 것이 늦다는 것을 알고 있지만 결과를 달성하기위한 작은 해킹이 있습니다.)

보기 페이지 아래에 더미보기를 추가하기 만하면 됩니다 .

<android.support.v4.view.ViewPager
     android:layout_width="match_parent"
     android:layout_height="match_parent">
</android.support.v4.view.ViewPager>

<RelativeLayout
     android:id="@+id/dummyView"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
</RelativeLayout>

그런 다음에을 추가 OnClickListener하십시오 RelativeLayout.

dummyView = (RelativeLayout) findViewById(R.id.dummyView);

dummyView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
         //Just leave this empty
    }
});

레이아웃, 배치 및 동작으로 약간의 창의력을 발휘하면 상상할 수있는 모든 것을 할 수있는 방법을 찾는 방법을 배우게됩니다. :)

행운을 빕니다!


이벤트 를 처리 할 필요가없는 경우 보다 쉬운 방법을 사용하는 setClickable것입니다 . setOnClickListeneronClick
— 카오스

이것은 또한 뷰 페이저 내의 터치를 차단하지 않습니까?
— Android 개발자

그렇습니다. 그것은 @androiddeveloper OP에서 요구하는 예상되는 동작입니다
— Dinuka 제이

@RickGrimesTheCoder 나는 당신이 내 질문을 이해했다고 생각하지 않습니다. 나는 viewpager의 조각 내에서보기를 의미합니다. 그들은 여전히 ​​만질 수 있습니까?
— Android 개발자

viewpager 자체에 클릭 리스너가 있기 때문에 그렇지 않습니다. 조각 내에 대화 형 요소가없는 경우에만 적합합니다. 예를 들어 동적으로 프래그먼트를 변경하는 Welcome ViewPager @androiddeveloper
— Dinuka Jay

12

나는 CustomViewPager슬쩍 컨트롤과 함께 썼다 :

public class ScrollableViewPager extends ViewPager {
    private boolean canScroll = true;
    public ScrollableViewPager(Context context) {
        super(context);
    }
    public ScrollableViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public void setCanScroll(boolean canScroll) {
        this.canScroll = canScroll;
    }
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return canScroll && super.onTouchEvent(ev);
    }
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return canScroll && super.onInterceptTouchEvent(ev);
    }
}

사용자가 설정 한 경우 canScroll에 true,이 ViewPager손가락으로 보내 주시면 될 수있다,false 반대로.

나는 이것을 내 프로젝트에서 사용하며 지금까지 훌륭하게 작동합니다.


1
ViewPager 안에 버튼이 있는데 클릭을 원하면 어떻게합니까? 이 솔루션은 viewpager 아래의 모든 클릭을 중지합니다 ..
— aimiliano

6

나는이 수업을 성공적으로 사용했다. 일부 장치에서 화살표를 사용하여 스 와이프하지 않거나 접근성을 위해 executeKeyEvent를 재정의 해야합니다.

import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.MotionEvent;

public class ViewPagerNoSwipe extends ViewPager {
    /**
     * Is swipe enabled
     */
    private boolean enabled;

    public ViewPagerNoSwipe(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.enabled = false; // By default swiping is disabled
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return this.enabled ? super.onTouchEvent(event) : false;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return this.enabled ? super.onInterceptTouchEvent(event) : false;
    }

    @Override
    public boolean executeKeyEvent(KeyEvent event) {
        return this.enabled ? super.executeKeyEvent(event) : false;
    }

    public void setSwipeEnabled(boolean enabled) {
        this.enabled = enabled;
    }

}

그리고 xml 에서 다음 과 같이 호출하십시오.

<package.path.ViewPagerNoSwipe
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

효과가있다. 스 와이프 만 비활성화되고 탭을 클릭하면 활성화됩니다. AS는 performClick()메소드가 대체되지 않음을 경고합니다 .
— CoolMind

5

Kotlin에서 내 솔루션은 위의 답변을 결합합니다.

class CustomViewPager(context: Context, attrs: AttributeSet): ViewPager(context, attrs) {
    var swipeEnabled = false

    override fun onTouchEvent(ev: MotionEvent?): Boolean {
        return if (swipeEnabled) super.onTouchEvent(ev) else false
    }

    override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
        return if (swipeEnabled) super.onInterceptTouchEvent(ev) else false
    }

    override fun executeKeyEvent(event: KeyEvent): Boolean {
        return if (swipeEnabled) super.executeKeyEvent(event) else false
    }
}

재정의 onInterceptTouchEvent()하면 자식 뷰가 입력을받지 못하게됩니다. 대부분의 경우 이것은 의도 된 동작이 아닙니다.
— Alex Semeniuk

각 조각의 자식 뷰와 상호 작용할 수있었습니다. 무엇을 말하는지 잘 모르겠습니다.
— Jeff Padgett

5

kotlin에서는 ViewPager 클래스를 상속하는 사용자 정의 위젯을 만들고 스 와이프 동작을 제어하기위한 플래그 값을 추가하여이 문제를 해결할 수 있습니다.

NoSwipePager.kt

class NoSwipePager(context: Context, attrs: AttributeSet) : ViewPager(context, attrs) {

    var pagingEnabled: Boolean = false

    override fun onTouchEvent(event: MotionEvent): Boolean {
        return if (this.pagingEnabled) {
            super.onTouchEvent(event)
        } else false
    }

    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        return if (this.pagingEnabled) {
            super.onInterceptTouchEvent(event)
        } else false
    }
}

xml에서

<your.package.NoSwipePager
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@id/tab_layout" />

프로그래밍 방식으로 스 와이프를 사용 중지합니다. kotlin-android-extensions플러그인이 build.gradle에 적용 되면 아래 코드를 작성하여 스 와이프를 비활성화 할 수 있습니다.

view_pager.pagingEnabled = false

그렇지 않으면 아래 코드를 사용하여 스 와이프를 비활성화 할 수 있습니다.

val viewPager : ViewPager = findViewById(R.id.view_pager)
viewPager.pagingEnabled = false

재정의 onInterceptTouchEvent()하면 자식 뷰가 입력을받지 못하게됩니다. 대부분의 경우 이것은 의도 된 동작 이 아닙니다 .
— Alex Semeniuk

@AlexSemeniuk 구현 후 문제가 있습니까? 일부 작업에 대해 리사이클 뷰 항목을 스 와이프하도록 설정했으며 정상적으로 작동합니다. 그래서 제 경우에는 구현이 잘 작동합니다.
— Sagar Chapagain

Sagar Chapagain : 물론 그렇습니다. 각 페이지에는 사용자 정의보기가 포함되어 있으며, 여기에는 스크롤, 드래그, 단일 및 긴 탭을 포함하여 다양한 방식으로 터치를 처리합니다. 호출 super.onInterceptTouchEvent(event)하지 않으면 이러한보기에서 입력을받지 않습니다 (문서화 된 onInterceptTouchEvent메소드의 목적 임 ).
— Alex Semeniuk

이 경우 자식 조각을 사용하고 백 스택을 유지해야합니다.
— Sagar Chapagain

이것이 현재 질문과 어떤 관련이 있습니까? 조각은 일부 컨테이너 ( Views ) 안에 배치 되고 자체 레이아웃에는 Views 가 포함 됩니다. ViewPager에 어떤 내용이 포함되어 있더라도 onInterceptTouchEvent()메서드 를 재정의 하면 내용 (콘텐츠)이 입력을받지 못하게 한다는 사실을 여전히 다루고 있습니다.
— Alex Semeniuk


1

특정 페이지 (이 예에서는 2 페이지)에서 스 와이프를 비활성화하는 또 다른 쉬운 솔루션 :

int PAGE = 2;
viewPager.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
        if (viewPager.getCurrentItem() == PAGE) {
                viewPager.setCurrentItem(PAGE-1, false);
                viewPager.setCurrentItem(PAGE, false);
                return  true;
        }
        return false;
}

1
This worked for me

viewPager.setOnTouchListener(new View.OnTouchListener() {
                                         @Override
                                         public boolean onTouch(View v, MotionEvent event) {
                                             if (viewPager.getCurrentItem() == 0) {
                                                 viewPager.setCurrentItem(-1, false);
                                                 return true;
                                             }
                                             else if (viewPager.getCurrentItem() == 1) {
                                                 viewPager.setCurrentItem(1, false);
                                                 return true;
                                             }
                                             else if (viewPager.getCurrentItem() == 2) {
                                                 viewPager.setCurrentItem(2, false);
                                                 return true;
                                             }
                                             return true;
                                         }
                                     });

1

확대 / 축소 및 이동을 지원 하는 ImageViews 및을 사용 하여 이미지 갤러리를 작성하는 경우 ViewPager여기에 설명 된 간단한 해결책을 참조하십시오. Phimpme Android (및 Github 샘플 -PhotoView에서 기본 ViewPager를 확장하여 확대 가능한 ImageView 구현) ). 이 솔루션은 ViewPager단독으로 는 작동하지 않습니다 .

public class CustomViewPager extends ViewPager {
    public CustomViewPager(Context context) {
        super(context);
    }

    public CustomViewPager(Context context, AttributeSet attrs)
    {
        super(context,attrs);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        try {
            return super.onInterceptTouchEvent(event);
        } catch (IllegalArgumentException e) {
            return false;
        }
    }
}

0

Xamarin에서 Android에 동일하게 구현하려면 C #으로의 번역이 있습니다.

속성의 이름을 " ScrollEnabled "로 지정했습니다. iOS는 excat과 동일한 이름을 사용하기 때문입니다. 따라서 두 플랫폼에서 동일한 이름을 지정하므로 개발자가 더 쉽게 사용할 수 있습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.Support.V4.View;
using Android.Util;

namespace YourNameSpace.ViewPackage {

    // Need to disable swiping for ViewPager, if user performs Pre DSA and the dsa is not completed yet
    // http://stackoverflow.com/questions/9650265/how-do-disable-paging-by-swiping-with-finger-in-viewpager-but-still-be-able-to-s
    public class CustomViewPager: ViewPager {
        public bool ScrollEnabled;

        public CustomViewPager(Context context, IAttributeSet attrs) : base(context, attrs) {
            this.ScrollEnabled = true;
        }

        public override bool OnTouchEvent(MotionEvent e) {
            if (this.ScrollEnabled) {
                return base.OnTouchEvent(e);
            }
            return false;
        }

        public override bool OnInterceptTouchEvent(MotionEvent e) {
            if (this.ScrollEnabled) {
                return base.OnInterceptTouchEvent(e);
            }
            return false;
        }

        // For ViewPager inside another ViewPager
        public override bool CanScrollHorizontally(int direction) {
            return this.ScrollEnabled && base.CanScrollHorizontally(direction);
        }

        // Some devices like the Galaxy Tab 4 10' show swipe buttons where most devices never show them
        // So, you could still swipe through the ViewPager with your keyboard keys
        public override bool ExecuteKeyEvent(KeyEvent evt) {
            return this.ScrollEnabled ? base.ExecuteKeyEvent(evt) : false;
        }
    }
}

.axml 파일에서 :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  <YourNameSpace.ViewPackage.CustomViewPager
      android:id="@+id/pager"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@android:color/white"
      android:layout_alignParentTop="true" />
</LinearLayout>

0

위 코드 중 아무것도 원활하게 작동하지 않습니다.

<HorizontalScrollView
                    android:id="@+id/horizontalScrollView"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:fillViewport="true">

                    <android.support.v4.view.ViewPager
                        android:id="@+id/pager"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent" />
                </HorizontalScrollView>

0

여기 내 구현입니다
스 와이프 애니메이션을 사용하지 않으려면 왼쪽과 오른쪽으로 swipeListener를 사용하고 애니메이션을 사용하지 않고 손가락으로 스크롤을 원할 수 있다는 입니다.

1 재정의 Viewpager방법 onInterceptTouchEvent및onTouchEvent

2- 나만의 만들기 GestureDetector

3- 스 와이프 제스처를 감지하고 setCurrentItem(item, false)

ViewPager

public class ViewPagerNoSwipe extends ViewPager {
    private final GestureDetector gestureDetector;
    private OnSwipeListener mOnSwipeListener;

    public void setOnSwipeListener(OnSwipeListener onSwipeListener) {
        mOnSwipeListener = onSwipeListener;
    }

    public ViewPagerNoSwipe(@NonNull Context context) {
        super(context);
        gestureDetector = new GestureDetector(context, new GestureListener());

    }

    public ViewPagerNoSwipe(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        gestureDetector = new GestureDetector(context, new GestureListener());


    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return true;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        gestureDetector.onTouchEvent(ev);
        return false;
    }

    public class GestureListener extends GestureDetector.SimpleOnGestureListener {

        private static final int SWIPE_THRESHOLD = 100;
        private static final int SWIPE_VELOCITY_THRESHOLD = 100;

        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            boolean result = false;
            try {
                float diffY = e2.getY() - e1.getY();
                float diffX = e2.getX() - e1.getX();
                if (Math.abs(diffX) > Math.abs(diffY)) {
                    if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                        if (diffX > 0) {
                            if(mOnSwipeListener!=null)
                            mOnSwipeListener.onSwipeRight();
                        } else {
                            if(mOnSwipeListener!=null)
                                mOnSwipeListener.onSwipeLeft();
                        }
                        result = true;
                    }
                } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        if(mOnSwipeListener!=null)
                            mOnSwipeListener.onSwipeBottom();
                    } else {
                        if(mOnSwipeListener!=null)
                            mOnSwipeListener.onSwipeTop();
                    }
                    result = true;
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            return result;
        }
    }

    public interface OnSwipeListener {

         void onSwipeRight();

        void onSwipeLeft();

        void onSwipeTop();

        void onSwipeBottom();
    }
}

ViewPager를 설정할 때 swipeListener를 설정하십시오.

postsPager.setOnSwipeListener(new ViewPagerNoSwipe.OnSwipeListener() {
            @Override
            public void onSwipeRight() {

              postsPager.setCurrentItem(postsPager.getCurrentItem() + 1,false);

            }

            @Override
            public void onSwipeLeft() {

            postsPager.setCurrentItem(postsPager.getCurrentItem() - 1, false);

            }
             ...
           }

0

방금 viewpager를 약간 사용자 정의하고 쉽게 스 와이프를 비활성화했습니다.

public class CustomViewPager extends ViewPager {

private boolean swipeLocked;

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

public CustomViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public boolean getSwipeLocked() {
    return swipeLocked;
}

public void setSwipeLocked(boolean swipeLocked) {
    this.swipeLocked = swipeLocked;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    return !swipeLocked && super.onTouchEvent(event);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    return !swipeLocked && super.onInterceptTouchEvent(event);
}

@Override
public boolean canScrollHorizontally(int direction) {
    return !swipeLocked && super.canScrollHorizontally(direction);
}
}

0

ViewPager2를 사용하는 경우 다음을 사용해야합니다.

viewpager.setUserInputEnabled(false);

로부터 문서 :

사용자 시작 스크롤을 활성화 또는 비활성화합니다. 여기에는 터치 입력 (스크롤 및 플링 제스처) 및 접근성 입력이 포함됩니다. 키보드 입력 비활성화는 아직 지원되지 않습니다. 사용자가 시작한 스크롤이 비활성화되면 setCurrentItem을 통한 프로그래밍 방식 스크롤이 계속 작동합니다. 기본적으로 사용자 시작 스크롤이 사용 가능합니다.

덕분에 : https://stackoverflow.com/a/61685871/9026710


-1
shareViewPager?.setOnTouchListener(object :View.OnTouchListener{
            override fun onTouch(v: View?, event: MotionEvent?): Boolean {
                for (PAGE in 0..shareViewPager.adapter!!.count){
                    if (shareViewPager.currentItem==PAGE){
                        shareViewPager.setCurrentItem(PAGE-1,false)
                        shareViewPager.setCurrentItem(PAGE,false)
                    }}
                return true
            }

        })
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.