ViewPager отключает прокрутку в определенном направлении

Я хочу отключить прокрутку, но только с правой стороны. Я нашел рабочее решение в этом ответе. К сожалению, это копирует весь источник ViewPager для достижения цели. Есть ли какие-либо методы, которые наследуют существующий класс, а не дублируют?

Ответы

Ответ 1

Я не уверен, что это именно то, что вам нужно: Мне нужен viewpager для мастера с максимальной страницей, которую пользователь не может передать.

В конце решение находилось в адаптере. Я изменил счет PagerAdapter и таким образом блокирует пользователя от прохождения максимальной страницы:

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

Когда пользователь перейдет на следующую страницу:

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

Таким образом, когда пользователь находится на максимальной странице, он не может прокручивать вправо.

Ответ 2

Здесь работает класс 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;
    }

Ответ 3

Еще один простой способ - использовать 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);
}

Это решение технически не полностью отключит салфетки, так как вы все равно увидите небольшую часть запрещенного слайда, когда вы совершаете движение салфетки. Но для некоторых приложений это может быть предпочтительным.

Ответ 4

Вы можете попробовать следующее:

Шаг 1: Создайте новый пользовательский класс, скажем "CustomViewPager". Класс наследует от "ViewPager" и включает новый настраиваемый метод под названием "setPagingEnabled" с целью включения/выключения прокрутки в зависимости от требования.

Шаг 2: Переопределите два метода: "onTouchEvent" и "onInterceptTouchEvent". Оба будут возвращать "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

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;
}

Ответ 6

Вы можете использовать методы beginFakeDrag() и endFakeDrag().

beginFakeDrag(), когда вы хотите отключить салфетки и endFakeDrag(), если вы хотите снова включить.

Пример: viewPager.beginFakeDrag();