Проблема с прокруткой Android ViewPager при использовании только одного элемента при использовании getPageWidth из PagerAdapter

У меня есть ViewPager с пользовательским PagerAdapter, который перезаписывает метод getPageWidth для возврата 0,3f, поэтому я могу показать несколько страниц на экране, как это предлагается в следующем блоге:

http://commonsware.com/blog/2012/08/20/multiple-view-viewpager-options.html

В этом случае ViewPager запускается пустым, и пользователь начинает заполнять страницы (изображения) по запросу. Изображения заполняются слева направо. Все работает нормально, и страницы создаются динамически, и их легко прокручивать, когда есть несколько изображений.

Однако существует проблема, когда создается менее трех страниц. Жест жестом с правой стороны (без содержимого) влево производит мерцание со страницами, движущимися слева направо, как если бы ViewPager пытался перенести первые страницы вправо, но позже перешел в исходное положение. Это происходит во время всего жеста и останавливается, когда вы покидаете жест. Поскольку я сказал, что этого не происходит, когда есть достаточно страниц, чтобы покрыть всю ширину экрана, и необходим реальный прокрутка.

Любые идеи?

Ответ 1

Я знаю, что это старый вопрос, но я просто искал решение и наткнулся на эту ссылку (что странно ссылается на этот вопрос). Во всяком случае, я смог найти решение, основанное на их комментариях. Основная идея состоит в том, чтобы разрешить сенсорные события на основе состояния булевого флага, который вы установили.

  • Расширить ViewPager при переопределении onInterceptTouchEvent и onTouchEvent только для вызова super, если вы установили флаг. Мой класс выглядит следующим образом:

    public class MyViewPager extends ViewPager {
    
        private boolean isPagingEnabled = false;
    
        public MyViewPager(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public MyViewPager(Context context) {
            super(context);
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent event) {
            if (isPagingEnabled) {
                return super.onInterceptTouchEvent(event);
            }
            return false;
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            if (isPagingEnabled) {
                return super.onTouchEvent(event);
            }
            return false;
        }
    
        public void setPagingEnabled(boolean pagingEnabled) {
            isPagingEnabled = pagingEnabled;
        }
    }
    
  • В вашем макете xml замените элементы com.android.support.v4.ViewPager элементами com.yourpackage.MyViewPager.

  • Так как вы возвращаете 0,3f из getPageWidth() в вашем пейджинговом адаптере, вы хотите, чтобы скроллинг включался, когда четвертый элемент был добавлен к нему. Сложная часть имеет всю эту строку кода, когда вы определяете свой адаптер пейджера и добавляете или удаляете любые объекты из списка поддержки адаптера.

    mPager.setPagingEnabled(items.size() > 3);
    

Ответ 2

Решение Rahuls работает, но если вы хотите автоматическое включение пейджинга в соответствии с содержимым, вы можете изменить ViewPager следующим образом:

public class MyViewPager extends ViewPager {

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

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

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    if (canScrollHorizontally(1)||canScrollHorizontally(-1)) {
        return super.onInterceptTouchEvent(event);
    }

    return false;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (canScrollHorizontally(1)||canScrollHorizontally(-1)) {
        return super.onTouchEvent(event);
    }

    return false;
}

}

Теперь, если ViewPager прокручивается, это позволит коснуться, иначе отключить.

Ответ 3

Мне удалось решить эту проблему в вашем методе getPageWidth(), если есть только одно изображение [вы можете узнать, проверяя размер массива или arraylist] return 1, если размер ввода больше 1 верните десятичное число. Вот код для этого.

@override
public float getPageWidth(int position){
  if(inpputsize==1){ 
      return 1.0;
  }
  return 0.9;  
}