Skip to content
This repository has been archived by the owner on Apr 19, 2018. It is now read-only.

added LoopingViewPager library project and changed all ViewPager occuran... #339

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions LoopingViewPager/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.imbryk.viewPager"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="4" />

</manifest>
56 changes: 56 additions & 0 deletions LoopingViewPager/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
LoopingViewPager
================

An android ViewPager extension allowing infinite scrolling.

This viewPager is fully compatible with [ViewPagerIndicator][1], and [PagerSlidingTabStrip][2]!



Usage
-----

To use it simply change `<android.support.v4.view.ViewPager>` to `<com.imbryk.viewPager.LoopViewPager>`

I your PagerAdapter is used only to create Views (i.e. you don't use FragmentPagerAdapter or FragmentStatePagerAdapter),
then no additional code changes are needed!


If you want to use LoopViewPager with FragmentPagerAdapter or FragmentStatePagerAdapter
additional changes in the adapter must be done.
The adapter must be prepared to create 2 extra items e.g.:

The original adapter creates 4 items: `[0,1,2,3]`
The modified adapter will have to create 6 items `[0,1,2,3,4,5]`
with mapping `realPosition=(position-1)%count`
`[0->3, 1->0, 2->1, 3->2, 4->3, 5->0]`


Sometimes "blinking" can be seen when paginating to first or last view.
To remove this effect, simply call setBoundaryCaching( true ) on your LoopViewPager,
or change DEFAULT_BOUNDARY_CASHING to true, if you want to set boundary caching
on all LoopViewPager instances



License
=======

Copyright 2013 Leszek Mzyk

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.



[1]: https://github.com/JakeWharton/Android-ViewPagerIndicator
[2]: https://github.com/astuetz/PagerSlidingTabStrip
Binary file added LoopingViewPager/libs/android-support-v4.jar
Binary file not shown.
15 changes: 15 additions & 0 deletions LoopingViewPager/project.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

android.library=true
# Project target.
target=android-17
171 changes: 171 additions & 0 deletions LoopingViewPager/src/com/imbryk/viewPager/LoopPagerAdapterWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*
* Copyright (C) 2013 Leszek Mzyk
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.imbryk.viewPager;

import android.os.Parcelable;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;

/**
* A PagerAdapter wrapper responsible for providing a proper page to
* LoopViewPager
*
* This class shouldn't be used directly
*/
public class LoopPagerAdapterWrapper extends PagerAdapter {

private PagerAdapter mAdapter;

private SparseArray<ToDestroy> mToDestroy = new SparseArray<ToDestroy>();

private boolean mBoundaryCaching;

void setBoundaryCaching(boolean flag) {
mBoundaryCaching = flag;
}

LoopPagerAdapterWrapper(PagerAdapter adapter) {
this.mAdapter = adapter;
}

@Override
public void notifyDataSetChanged() {
mToDestroy = new SparseArray<ToDestroy>();
super.notifyDataSetChanged();
}

int toRealPosition(int position) {
int realCount = getRealCount();

int realPosition = (position-1) % realCount;
if (realPosition < 0)
realPosition += realCount;

return realPosition;
}

public int toInnerPosition(int realPosition) {
int position = (realPosition + 1);
return position;
}

private int getRealFirstPosition() {
return 1;
}

private int getRealLastPosition() {
return getRealFirstPosition() + getRealCount() - 1;
}

@Override
public int getCount() {
return mAdapter.getCount() + 2;
}

public int getRealCount() {
return mAdapter.getCount();
}

public PagerAdapter getRealAdapter() {
return mAdapter;
}

@Override
public Object instantiateItem(ViewGroup container, int position) {
int realPosition = (mAdapter instanceof FragmentPagerAdapter || mAdapter instanceof FragmentStatePagerAdapter)
? position
: toRealPosition(position);

if (mBoundaryCaching) {
ToDestroy toDestroy = mToDestroy.get(position);
if (toDestroy != null) {
mToDestroy.remove(position);
return toDestroy.object;
}
}
return mAdapter.instantiateItem(container, realPosition);
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
int realFirst = getRealFirstPosition();
int realLast = getRealLastPosition();
int realPosition = (mAdapter instanceof FragmentPagerAdapter || mAdapter instanceof FragmentStatePagerAdapter)
? position
: toRealPosition(position);

if (mBoundaryCaching && (position == realFirst || position == realLast)) {
mToDestroy.put(position, new ToDestroy(container, realPosition,
object));
} else {
mAdapter.destroyItem(container, realPosition, object);
}
}

/*
* Delegate rest of methods directly to the inner adapter.
*/

@Override
public void finishUpdate(ViewGroup container) {
mAdapter.finishUpdate(container);
}

@Override
public boolean isViewFromObject(View view, Object object) {
return mAdapter.isViewFromObject(view, object);
}

@Override
public void restoreState(Parcelable bundle, ClassLoader classLoader) {
mAdapter.restoreState(bundle, classLoader);
}

@Override
public Parcelable saveState() {
return mAdapter.saveState();
}

@Override
public void startUpdate(ViewGroup container) {
mAdapter.startUpdate(container);
}

/*
* End delegation
*/

/**
* Container class for caching the boundary views
*/
static class ToDestroy {
ViewGroup container;
int position;
Object object;

public ToDestroy(ViewGroup container, int position, Object object) {
this.container = container;
this.position = position;
this.object = object;
}
}

}
Loading