web-dev-qa-db-ja.com

ViewPagerは特定の方向へのスワイプを無効にします

スワイプを無効にしたいのですが、右側のみです。 this の答えに実用的な解決策が見つかりました。残念ながら、これはViewPagerソース全体をコピーして目標を達成します。既存のクラスを継承し、複製しないメソッドはありますか?

18
WonderCsabo

これが必要なものかどうかはわかりません。ユーザーが渡すことができない最大ページを持つウィザードのビューページャーが必要でした。

最後に、ソリューションはアダプターにありました。 PagerAdapterの数を変更しました。これにより、ユーザーが最大ページを渡すことができなくなります。

@Override
public int getCount() {
    return mProgress; //max page + 1
}

ユーザーが次のページに進むとき:

private void setWizardProgress(int progress) {
    if(progress > mProgress) {
        mProgress = progress;
        mWizardPagerAdapter.notifyDataSetChanged();
    }
}

この方法では、ユーザーが最大ページにいるとき、右にスクロールできません。

22
Aviv Mor

以下は、方向ページングを無効にする可能性がある作業用のViewPagerクラスです。すべての ここで回答 を確認してください。

public class CustomViewPager extends ViewPager {
    private float initialXValue;
    private SwipeDirection direction;

    public CustomViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.direction = SwipeDirection.all;
    }

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

        return false;
    }

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

        return false;
    }

    private boolean IsSwipeAllowed(MotionEvent event) {
        if(this.direction == SwipeDirection.all) return true;

        if(direction == SwipeDirection.none )//disable any swipe
            return false;

        if(event.getAction()==MotionEvent.ACTION_DOWN) {
            initialXValue = event.getX();
            return true;
        }

        if(event.getAction()==MotionEvent.ACTION_MOVE) {
            try {
                float diffX = event.getX() - initialXValue;
                if (diffX > 0 && direction == SwipeDirection.right ) {
                    // swipe from left to right detected
                    return false;
                }else if (diffX < 0 && direction == SwipeDirection.left ) {
                    // swipe from right to left detected
                    return false;
                }
            } catch (Exception exception) {
                exception.printStackTrace();
            }
        }

        return true;
    }

    public void setAllowedSwipeDirection(SwipeDirection direction) {
        this.direction = direction;
    }
19
andre719mv

別の簡単な方法は、setCurrentItem()を使用して、特定の位置に到達した場合に目的のスライドにスクロールして戻ることです。たとえば、これは前方スワイプのみを許可します:

mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}

    @Override
    public void onPageSelected(int position) {
        if(position < mProgress) {
            mViewPager.setCurrentItem(mProgress, true);
        } else {
            mProgress = position;
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {}
});

または、最大のスライドが必要な場合:

if(position > 4) {
    mViewPager.setCurrentItem(4, true);
}

このソリューションでは、技術的にスワイプを完全に無効にすることはできません。スワイプを行ったときに、許可されていないスライドの一部が表示されるためです。しかし、一部のアプリケーションでは、これが優先される場合があります。

8
jwBurnside

以下を試すことができます:

ステップ1:CustomViewPager」という新しいカスタムクラスを作成します。このクラスは「ViewPager」を継承し、要件に応じてスワイプを有効/無効にする目的で「setPagingEnabled」と呼ばれる新しいカスタマイズされたメソッドを含みます。

Step2:onTouchEvent」と「onInterceptTouchEvent」の2つのメソッドをオーバーライドします。ページングを完全に無効にする場合、どちらも「false」を返します。

ステップ3:レイアウトファイルの「ViewPager」タグをカスタマイズされたクラスに置き換えます。

    <package_name.customviewpager 
     Android:id="@+id/customViewPager" 
     Android:layout_height="match_parent" 
     Android:layout_width="match_parent" />

ステップ4: CustomViewPager.Java

    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 && detectSwipeToRight(event)) {
        return super.onTouchEvent(event);
    }

    return false;
}

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

    return false;
}

// To enable/disable swipe 
public void setPagingEnabled(boolean enabled) {
    this.enabled = enabled;
}

// Detects the direction of swipe. Right or left. 
// Returns true if swipe is in right direction
public boolean detectSwipeToRight(MotionEvent event){

 int initialXValue = 0; // as we have to detect swipe to right
 final int SWIPE_THRESHOLD = 100; // detect swipe
 boolean result = false;

        try {                
            float diffX = event.getX() - initialXValue;

                if (Math.abs(diffX) > SWIPE_THRESHOLD ) {
                    if (diffX > 0) {
                        // swipe from left to right detected ie.SwipeRight
                        result = false;
                    } else {
                        // swipe from right to left detected ie.SwipeLeft
                        result = true;
                    }
                }
            } 
         catch (Exception exception) {
            exception.printStackTrace();
        }
        return result;
    }
}
5
Ritesh Gune
private float initialXValue;
@Override
public boolean onTouchEvent(MotionEvent event) {
    if (this.mEnabled) {
        return super.onTouchEvent(event);
    }
    if(event.getAction()==MotionEvent.ACTION_DOWN){
        initialXValue = event.getX();
    }else if(event.getAction()==MotionEvent.ACTION_MOVE){
        if(detectSwipeToRight(event)){
            System.out.println("right swipe detected");
        }
    }
    return true;
}

private boolean detectSwipeToRight(MotionEvent event) {
    final int SWIPE_THRESHOLD = 100; // detect swipe
    boolean result = false;

    try {
        float diffX = event.getX() - initialXValue;
        if (Math.abs(diffX) > SWIPE_THRESHOLD) {
            if (diffX < 0) {
                // swipe from right to left detected ie.SwipeLeft
                result = true;
            }
        }
    } catch (Exception exception) {
        exception.printStackTrace();
    }
    return result;
}
1
Deepanshu

メソッドbeginFakeDrag()およびendFakeDrag()を使用できます。

beginFakeDrag()スワイプを無効にする場合はendFakeDrag()を再度有効にする場合。

このように:viewPager.beginFakeDrag();

1
Ferran Ribell