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)하는 두 가지 방법을 사용하지 않으려면 : onTouchEventonInterceptTouchEvent. 페이징이 비활성화 된 경우 둘 다 "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
당신은 당신의 단순화 onTouchEventonInterceptTouchEvent함께 방법을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을 내가 어떻게 사용하는 모든 세부 사항을 추가 viewpager2RecyclerView.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);
    }
}

사용자가 설정 한 경우 canScrolltrue,이 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방법 onInterceptTouchEventonTouchEvent

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.