Android ViewPager scrolling issue with only one item when using getPageWidth from PagerAdapter
Asked Answered
I

3

17

I have a ViewPager with a custom PagerAdapter that overwrites the method getPageWidth to return 0.3f, so I can show multiple pages in the screen, as suggested in the following blog:

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

In this case the ViewPager starts empty and the user starts filling the pages (images) as requested. The images are filled from left to right. All is working fine and the pages are dinamically created, and it is easy to swipe between them when there are multiple images.

However there is a problem when there are less than three pages instantiated. A swipe gesture from right (no content) to left produces a flickering with pages moving from left to right alternatively, as if the ViewPager were trying to move the first pages to right but later turning to its original position. This happens during the whole gesture, and stop when leaving the gesture. As I said this does not happen when there are pages enough to cover the whole screen width and a real scroll is necessary.

Any Ideas?

Irenics answered 27/8, 2013 at 9:59 Comment(0)
A
12

I know this is an old question, but I was just looking for a solution and came across this link (which oddly references this question). Anyway, I was able to figure out a solution based on their comments. The basic idea is to allow touch events based on the state of a boolean flag which you set.

  1. Extend ViewPager on override onInterceptTouchEvent & onTouchEvent to only call super if you've set the flag. My class looks like this:

    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;
        }
    }
    
  2. In your layout xml, replace your com.android.support.v4.ViewPager elements with com.yourpackage.MyViewPager elements.

  3. Since you return 0.3f from getPageWidth() in your pager adapter, you would want scrolling enabled when the fourth item has been added to it. The tricky part is having this line of code everywhere when you define your pager adapter, and add or remove any objects from the adapter backing list.

    mPager.setPagingEnabled(items.size() > 3);
    
Agnosia answered 23/9, 2013 at 7:13 Comment(0)
V
12

Rahuls solution works, but if you want auto enabling of paging according to content, you can modify ViewPager like this:

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

}

Now, if the ViewPager is scrollable, it will allow touches, otherwise disable.

Valorie answered 5/6, 2015 at 10:54 Comment(0)
A
1

I was able to solve it this way, in your getPageWidth() method,if there is only one image[you can get to know by checking size of array or arraylist] return 1, if the input size is greater than 1 return your decimal. Here's the code to achieve this.

@override
public float getPageWidth(int position){
  if(inpputsize==1){ 
      return 1.0;
  }
  return 0.9;  
}
Abutter answered 16/6, 2015 at 4:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.