Reputation: 44220
Infinite looping viewpagers rely on an illusion where the count of items is increased to an arbitrarily large number, which are mapped via modulus to index positions in a list.
The problem with this being that indicators such as Circle page indicators get the arbitrarily long count of numbers, because they use the getCount()
method of the host PagerAdapter
, completely breaking down the illusion of infinite looping.
Ie. You have 3 items you want to loop through, you set the pageradapter count to 1000, when the user gets to item 3 and swipes to item "4", the item 1 shows again. But the indicator shows you are at item 4 and that there are hundreds of other items to swipe to. Instead of just looping between 3 indicator selections.
Is there a solution for this?
Upvotes: 1
Views: 5869
Reputation: 41
I didn't want to spend time with new libraries. So, I code a simple OnPageChangeListener for infinite viewpagers with circle indicator (ImageView). It works well. AutoScrollViewPager is used as infinite viewPager. Indicator changes when viewpager scrolled half of the page not when scrolling is over.
Screenshot (circles are images is):
Usage:
bannerPager.setOnPageChangeListener(new OnPageChangeListenerForInfiniteIndicator(getActivity(), bannerList, bannerPager.getCurrentItem()));
xml:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="@dimen/home_banner_indicator_container_height">
<LinearLayout
android:id="@+id/container_home_page_indicator"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_marginBottom="@dimen/home_banner_indicator_container_inner_margin_vertical"
android:layout_marginTop="@dimen/home_banner_indicator_container_inner_margin_vertical"
android:orientation="horizontal">
</LinearLayout>
</RelativeLayout>
The OnPageChangeListenerForInfiniteIndicator:
import android.app.Activity;
import android.support.v4.view.ViewPager;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.kartaca.rbtpicker.R;
import com.kartaca.rbtpicker.model.Banner;
import java.util.ArrayList;
import java.util.List;
/**
* Created by amadeus on 9/18/15.
*/
public class OnPageChangeListenerForInfiniteIndicator implements ViewPager.OnPageChangeListener {
private Activity activity;
private List<ImageView> pageIndicatorList = new ArrayList<ImageView>();
private List<Banner> bannerList;
private LinearLayout containerIndicator;
private int viewPagerActivePosition;
private int positionToUse = 0;
private int actualPosition;
public OnPageChangeListenerForInfiniteIndicator(Activity activity, List<Banner> bannerList, int currentItem) {
this.activity = activity;
this.bannerList = bannerList;
this.actualPosition = currentItem;
this.viewPagerActivePosition = currentItem;
loadIndicators();
}
private void loadIndicators() {
containerIndicator = (LinearLayout) activity.findViewById(R.id.container_home_page_indicator);
if (pageIndicatorList.size() < 1) {
for (Banner banner : bannerList) {
ImageView imageView = new ImageView(activity);
imageView.setImageResource(R.drawable.banner_pagination_normal);// normal indicator image
imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
imageView.setLayoutParams(new ViewGroup.LayoutParams(activity.getResources().getDimensionPixelOffset(R.dimen.home_banner_indicator_width),
ViewGroup.LayoutParams.MATCH_PARENT));
pageIndicatorList.add(imageView);
}
}
containerIndicator.removeAllViews();
for (int x = 0; x < pageIndicatorList.size(); x++) {
ImageView imageView = pageIndicatorList.get(x);
imageView.setImageResource(x == positionToUse ? R.drawable.banner_pagination_active :
R.drawable.banner_pagination_normal); // active and notactive indicator
containerIndicator.addView(imageView);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
actualPosition = position;
int positionToUseOld = positionToUse;
if (actualPosition < viewPagerActivePosition && positionOffset < 0.5f) {
positionToUse = actualPosition % bannerList.size();
} else {
if (positionOffset > 0.5f) {
positionToUse = (actualPosition + 1) % bannerList.size();
} else {
positionToUse = actualPosition % bannerList.size();
}
}
if (positionToUseOld != positionToUse) {
loadIndicators();
}
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == 0) {
viewPagerActivePosition = actualPosition;
positionToUse = viewPagerActivePosition % bannerList.size();
loadIndicators();
}
}
}
Upvotes: 1
Reputation: 8284
Take a look at InfinitePageIndicator project, maybe it is something that you need.
Upvotes: 0