ViewPager show next and before item preview on screen - android

I want to show viewpager next and before page preview in screen. Before and next page show deep in screen and slide next page with deep animation.
You can look this image
How can i do it?

Finally, i did it :) I modify this answer Android - Carousel like widget which displays a portion of the left and right elements
You can look this code.
//pager settings
pager.setClipToPadding(false);
pager.setPageMargin(24);
pager.setPadding(48, 8, 48, 8);
pager.setOffscreenPageLimit(3);
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
Log.i("", "onPageScrolled: " + position);
CampaignPagerFragment sampleFragment = (CampaignPagerFragment) ((CampaignPagerAdapter) pager.getAdapter()).getRegisteredFragment(position);
float scale = 1 - (positionOffset * RATIO_SCALE);
// Just a shortcut to findViewById(R.id.image).setScale(scale);
sampleFragment.scaleImage(scale);
if (position + 1 < pager.getAdapter().getCount()) {
sampleFragment = (CampaignPagerFragment) ((CampaignPagerAdapter) pager.getAdapter()).getRegisteredFragment(position + 1);
scale = positionOffset * RATIO_SCALE + (1 - RATIO_SCALE);
sampleFragment.scaleImage(scale);
}
}
#Override
public void onPageSelected(int position) {
Log.i("", "onPageSelected: " + position);
}
#Override
public void onPageScrollStateChanged(int state) {
Log.i("", "onPageScrollStateChanged: " + state);
if (state == ViewPager.SCROLL_STATE_IDLE) {
CampaignPagerFragment fragment = (CampaignPagerFragment) ((CampaignPagerAdapter) pager.getAdapter()).getRegisteredFragment(pager.getCurrentItem());
fragment.scaleImage(1);
if (pager.getCurrentItem() > 0) {
fragment = (CampaignPagerFragment) ((CampaignPagerAdapter) pager.getAdapter()).getRegisteredFragment(pager.getCurrentItem() - 1);
fragment.scaleImage(1 - RATIO_SCALE);
}
if (pager.getCurrentItem() + 1 < pager.getAdapter().getCount()) {
fragment = (CampaignPagerFragment) ((CampaignPagerAdapter) pager.getAdapter()).getRegisteredFragment(pager.getCurrentItem() + 1);
fragment.scaleImage(1 - RATIO_SCALE);
}
}
}
});
//PagerAdapter
public class CampaignPagerAdapter extends FragmentStatePagerAdapter {
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public CampaignPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public int getCount() {
return 5;
}
#Override
public Fragment getItem(int position) {
return new CampaignPagerFragment();
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
}
for ex: https://github.com/mrleolink/SimpleInfiniteCarousel..
Hello, One thing that is missing
sampleFragment.scaleImage(scale);
It is a method created in CampaignPagerFragment and it scale the fragment rootView..
e.g public void scaleImage(float scaleX)
{
rootView.setScaleY(scaleX);
rootView.invalidate();
}

You can use PagerTransformer to ViewPager :-
mViewPager.setPageTransformer(false, new ViewPager.PageTransformer() {
#Override
public void transformPage(View page, float position) {
// do transformation here
}
});
Use this link for complete tutorial :-
http://andraskindler.com/blog/2013/create-viewpager-transitions-a-pagertransformer-example/
Hope this help you :)

viewPager.setPageMargin(100);
viewPager.setPageTransformer(false, new ViewPager.PageTransformer()
{
#Override
public void transformPage(View page, float position)
{
int pageWidth = viewPager.getMeasuredWidth() -
viewPager.getPaddingLeft() - viewPager.getPaddingRight();
int pageHeight = viewPager.getHeight();
int paddingLeft = viewPager.getPaddingLeft();
float transformPos = (float) (page.getLeft() -
(viewPager.getScrollX() + paddingLeft)) / pageWidth;
int max = pageHeight / 10;
if (transformPos < -1)
{
// [-Infinity,-1)
// This page is way off-screen to the left.
page.setAlpha(0.5f);// to make left transparent
page.setScaleY(0.7f);
}
else if (transformPos <= 1)
{
// [-1,1]
page.setScaleY(1f);
}
else
{
// (1,+Infinity]
// This page is way off-screen to the right.
page.setAlpha(0.5f);// to make right transparent
page.setScaleY(0.7f);
}
}
});

I think this is the simplest and cleanest solution.
float scaleFactor = 0.85f;
viewPager.setPageMargin(-35);
viewPager.setOffscreenPageLimit(2);
viewPager.setPageTransformer(false, new ViewPager.PageTransformer() {
#Override
public void transformPage(#NonNull View page, float position) {
page.setScaleY((1 - Math.abs(position) * (1 - scaleFactor)));
page.setScaleX(scaleFactor + Math.abs(position) * (1 - scaleFactor));
}
});

I did this by changing my viewpager's padding based on the position.
carouselViewHolder.carouselViewPager.setPadding(Utils.dpToPixels(context, 12), 0, Utils.dpToPixels(context, paddingRequired - 12), 0); // initial padding for position 0
carouselViewHolder.carouselViewPager.setPageMargin(Utils.dpToPixels(context, 12)); // margin between pages
carouselViewHolder.carouselViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
if (position != 0) {
if (position == playCardData.getPlayCards().size() - 1) {
carouselViewHolder.carouselViewPager.setPadding(Utils.dpToPixels(context, finalPaddingRequired - 12), 0, Utils.dpToPixels(context, 12), 0);
} else
carouselViewHolder.carouselViewPager.setPadding(Utils.dpToPixels(context, finalPaddingRequired / 2), 0, Utils.dpToPixels(context, finalPaddingRequired / 2), 0);
} else {
carouselViewHolder.carouselViewPager.setPadding(Utils.dpToPixels(context, 12), 0, Utils.dpToPixels(context, finalPaddingRequired - 12), 0);
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});

Related

How to implement stack transformation in vertical viewpager

How to implement stack transformation in VerticalViewPager,Here is my code which i have implemented VerticalViewPager with stack transformation but the issue is it is fading out, I want to remove fading out while swipe up the page.
public class VerticalViewPager extends Activity {
private static final float MIN_SCALE = 0.75f;
PagerAdapter adapter;
private static final float MIN_ALPHA = 0.75f;
private boolean a;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.verticalviewpager);
final fr.castorflex.android.verticalviewpager.VerticalViewPager verticalViewPager = (fr.castorflex.android.verticalviewpager.VerticalViewPager) findViewById(R.id.verticalviewpager);
adapter = new MyCustomAdapter(VerticalViewPager.this, SplashScreen.newsidArray, SplashScreen.newsdescArray, SplashScreen.newstitleArray,
SplashScreen.newsimageArray, SplashScreen.newsdateArray, SplashScreen.newsauthorArray, SplashScreen.newsurlArray);
verticalViewPager.setOffscreenPageLimit(1);
verticalViewPager.setAdapter(adapter);
verticalViewPager.setPageTransformer(false, new PageTransformer() {
#Override
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
view.setAlpha(1);
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1F-position);
view.setTranslationY((int) ((float) (pageHeight) * -position));
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
});
verticalViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageScrollStateChanged(int state) {
}
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
int page = verticalViewPager.getCurrentItem();
Log.e("page",String.valueOf(page));
if((page+1)== MyCustomAdapter.nodata){
// Toast.makeText(VerticalViewPager.this,"No News Available To Swipeup",500).show();
final Toast toast = Toast.makeText(getApplicationContext(), "No News Available To Swipeup", Toast.LENGTH_SHORT);
toast.show();
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
toast.cancel();
}
}, 500);
}
}
public void onPageSelected(int position) {
SplashScreen.myCustomPosition = position;
}
});
}
}

How to remove fading animation in vertical ViewPager in Android

Above is my issue screenshot. I just want to remove the opacity while I swipe up and down. When I swipe down, the current page turns transparent. I need to remove that transparency. Instead of extending the ViewPager, I have extended the activity. Can anyone give me solution for this issue?
public class VerticalViewPager extends Activity {
private static final float MIN_SCALE = 0.75f;
PagerAdapter adapter;
private static final float MIN_ALPHA = 0.75f;
private boolean a;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.verticalviewpager);
fr.castorflex.android.verticalviewpager.VerticalViewPager verticalViewPager = (fr.castorflex.android.verticalviewpager.VerticalViewPager) findViewById(R.id.verticalviewpager);
adapter = new MyCustomAdapter(VerticalViewPager.this, SplashScreen.newsidArray, SplashScreen.newsdescArray, SplashScreen.newstitleArray,
SplashScreen.newsimageArray, SplashScreen.newsdateArray, SplashScreen.newsauthorArray, SplashScreen.newsurlArray);
verticalViewPager.setOffscreenPageLimit(1);
verticalViewPager.setAdapter(adapter);
verticalViewPager.setPageTransformer(false, new PageTransformer() {
#Override
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position <= -1.0F) {
view.setAlpha(1);
Log.e("1", "test1");
} else if (position < 0F) {
view.setAlpha(1);
Log.e("2", "test2");
} else if (position >= 0F) {
view.setAlpha(0.9F - position);
view.setTranslationY((int) ((float) (pageHeight) * -position));
Log.e("3", "test3" + position);
} else if (position > 1.0F) {
view.setAlpha(1);
// view.setTranslationX(position < 0 ? 0f : -pageHeight * position);
Log.e("4", "test4");
}
}
});
}
}
Please try this.
And you have to confirm not using setAlpha() anywhere for page layout.(e.g. layout xml)
verticalViewPager.setPageTransformer(false, new ViewPager.PageTransformer() {
#Override
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position >= 0) {
view.setTranslationY(position < 0 ? 0f : -pageHeight * position);
}
}
});
I got the answer, you need to set the background for the view you are animating. By default it is transparent
android:background="#FFFFFF"

Android viewpager as like carousel

In my android application i have used viewpager, but i need to change the view of viewpager as like below
My Adapter
pager.setPageTransformer(false, new ViewPager.PageTransformer() {
#Override
public void transformPage(View page, float position) {
// do transformation here
// page.setRotationY(position * -40);
final float normalizedposition = Math.abs(Math.abs(position) - 1);
page.setScaleX(normalizedposition / 2 + 0.4f);
page.setScaleY(normalizedposition / 2 + 0.4f);
}
});
pager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
pager.setCurrentItem(position);
}
#Override
public void onPageScrolled(int position, float positionOffset,
int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
can anyone suggest how to achieve this
All answers are most welcome

Issue using ViewPager and PageTransformer with Android API <11

I need to write a custom transition for a ViewPager on an app with android:minSdkVersion="9".
I'm trying to run the ZoomOutPageTransformer given here.
I get no compiling error, and on a Samsung Galaxy S running Android 2.3.3 (API 10), the line
pager.setPageTransformer(true, new ZoomOutPageTransformer());
does not give any error, but the code in ZoomOutPageTransformer's transformPage is never executed.
The code works perfectly if I set android:minSdkVersion="11" and use my Nexus 4 (API 17).
Can these PageTransformers be used with API 9 and 10? Otherwise, how can I create custom transitions for ViewPager?
EDIT
Here's the code I use:
public class HomeFragment extends Fragment{
ViewPager mNewsTitlePager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.home_content, container, false);
}
#Override
public void onActivityCreated (Bundle savedInstanceState){
super.onActivityCreated(savedInstanceState);
mNewsTitlePager = (ViewPager) getView().findViewById(R.id.news_title_pager);
mNewsTitlePager.setPageTransformer(true, new ZoomOutPageTransformer());
mNewsTitlePager.setAdapter(new NewsPagerAdapter(news_item_list));
}
private class NewsPagerAdapter extends PagerAdapter {
private List<News> news_item_list;
private LayoutInflater inflater;
NewsPagerAdapter(List<News> news_item_list) {
this.news_item_list = news_item_list;
inflater = getActivity().getLayoutInflater();
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
#Override
public void finishUpdate(View container) {
}
#Override
public int getCount() {
return this.news_item_list.size();
}
#Override
public Object instantiateItem(ViewGroup view, int position) {
TextView news_title = (TextView) inflater.inflate(R.layout.news_title_item, view, false);
news_title.setText(news_item_list.get(position).title);
((ViewPager) view).addView(news_title, 0);
return news_title;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
}
#Override
public Parcelable saveState() {
return null;
}
#Override
public void startUpdate(View container) {
}
}
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
private float MIN_SCALE = 0.85f;
private float MIN_ALPHA = 0.5f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
// Modify the default slide transition to shrink the page as well
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
} else {
view.setTranslationX(-horzMargin + vertMargin / 2);
}
// Scale the page down (between MIN_SCALE and 1)
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
// Fade the page relative to its size.
view.setAlpha(MIN_ALPHA +
(scaleFactor - MIN_SCALE) /
(1 - MIN_SCALE) * (1 - MIN_ALPHA));
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
}
I copied the ViewPager class from here and removed the if statement for the version and called it TransformableViewPager
public void setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) {
if (Build.VERSION.SDK_INT >= 11) {
final boolean hasTransformer = transformer != null;
final boolean needsPopulate = hasTransformer != (mPageTransformer != null);
mPageTransformer = transformer;
setChildrenDrawingOrderEnabledCompat(hasTransformer);
if (hasTransformer) {
mDrawingOrder = reverseDrawingOrder ? DRAW_ORDER_REVERSE : DRAW_ORDER_FORWARD;
} else {
mDrawingOrder = DRAW_ORDER_DEFAULT;
}
if (needsPopulate) populate();
}
}
I also had to change all PageTransformer to ViewPager.PageTransformer. Then did the transformations in ZoomOutPageTranformer like this,
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB){
// > 11 version
view.setAlpha(0);
}
else
{
// Nine Old Androids version
ViewHelper.setAlpha(view, 0);
}
This worked even for 2.2
Ok: I got the answer at the beginning of the doc:
As property animation is only supported as of Android 3.0 and forward, setting a PageTransformer on a ViewPager on earlier platform versions will be ignored.
I'll use ViewFlipper instead.
None of the answers above are the correct answer even if they work,
Here is mine, do not forget to add nineoldandroids.jar to your libs folder:
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.85f;
private static final float MIN_ALPHA = 0.5f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) {
ViewHelper.setAlpha(view, 0);
} else if (position <= 1) { // [-1,1]
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
ViewHelper.setTranslationX(view,horzMargin - vertMargin / 2);
} else {
ViewHelper.setTranslationX(view,-horzMargin + vertMargin / 2);
}
ViewHelper.setScaleX(view,scaleFactor);
ViewHelper.setScaleY(view, scaleFactor);
ViewHelper.setAlpha(view, MIN_ALPHA + (scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA));
} else {
ViewHelper.setAlpha(view,0);
}
}
}

Implementing Circular Scrolling In PagerAdapter

I am using PagerAdapter for horizontal swiping for showing newspaper pages in my app.
Currently I want to implement the circular scrolling in this app.Right now what I have done is whenever I am getting on last page I try to set the currentItem to first pagei.e that functionality working for last page to first page,but the problem is that how can I go to last page from first page.
Here I am pasting my code related to pagerAdapter & onPageChangeListener:-
awesomeAdapter = new AwesomePagerAdapter(awesomePager);
awesomePager.setAdapter(awesomeAdapter);
awesomePager.setPageMargin(10);
awesomePager.setOnPageChangeListener(new OnPageChangeListener() {
int lastPosition;
float posOffset = 0;
#Override
public void onPageSelected(int position) {
viewerPage = position;
CommonLogic.logMessage("Viewer Page:- "+ viewerPage, TAG, Log.VERBOSE);
posOffset = 0;
}
#Override
public void onPageScrolled(int position,float positionOffset,int positionOffsetPixels) {
if (positionOffset == 0 && positionOffsetPixels == 0 && position != 0) {
lastPosition = position;
}
posOffset -= positionOffset;
CommonLogic.logMessage(" Position:- "
+ position + " Position Offset:- " + positionOffset
+ " Position Offset Variable:- "
+ posOffset
+ " Position Offset Pixels:- "
+ positionOffsetPixels
+ " Last Position " + lastPosition,
TAG, Log.VERBOSE);
CommonLogic.logMessage(" Last Position "
+ lastPosition, TAG, Log.VERBOSE);
}
#Override
public void onPageScrollStateChanged(int state) {
// To Detect the Last Page & This Sets it to first page.This working fine.
if (state == ViewPager.SCROLL_STATE_DRAGGING && viewerPage == (uris.size() - 1)) {
CommonLogic.logMessage("Scroll State Changed ", TAG,Log.VERBOSE);
postDelayed(new Runnable() {
#Override
public void run() {
awesomePager.setCurrentItem(0, true);
}
}, 200);
}
// I have also used this to detect whether the user is on first & try to move on last page,but it is not working well.
else if (state == ViewPager.SCROLL_STATE_DRAGGING && (lastPosition == 0 || lastPosition == (uris.size() - 1)) && viewerPage == 0 && posOffset <= 0) {
CommonLogic.logMessage( "Scroll State Changed ", TAG,Log.VERBOSE);
postDelayed(new Runnable() {
#Override
public void run() {
awesomePager.setCurrentItem((uris.size() - 1), true);
}
}, 200);
}
}
}
});
Also the PagerAdapter i.e AwesomweAdapter in my case,is also as folllows:-
private class AwesomePagerAdapter extends PagerAdapter {
ViewPager pdfContainer;
DocumentNewView documentNewView;
CustomViewPager customViewPager;
public AwesomePagerAdapter(CustomViewPager awesomePager) {
this.customViewPager = awesomePager;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
#Override
public int getCount() {
return uris.size();
}
public DocumentNewView addViewAt(int position, DocumentNewView mainView) {
CommonLogic.logMessage("Position of View:- " + position, TAG,
Log.VERBOSE);
pdfContainer.addView(mainView);
return mainView;
}
/**
* Create the page for the given position. The adapter is responsible
* for adding the view to the container given here, although it only
* must ensure this is done by the time it returns from
* {#link #finishUpdate()}.
*
* #param container
* The containing View in which the page will be shown.
* #param position
* The page position to be instantiated.
* #return Returns an Object representing the new page. This does not
* need to be a View, but can be some other container of the
* page.
*/
#Override
public Object instantiateItem(View collection, int position) {
CommonLogic
.logMessage("Instantiate Item Called ", TAG, Log.VERBOSE);
documentNewView = new DocumentNewView(cxt, display, customViewPager);
documentNewView.setPdfContext(new PdfContext());
CodecDocument codecDocument = documentNewView.open(uris
.get(position));
documentNewView.renderDocument(codecDocument);
documentNewView.setMaxZoom(4f);
documentNewView.setVerticalScrollBarEnabled(true);
codecDocument = null;
this.pdfContainer = (ViewPager) collection;
return addViewAt(position, documentNewView);
}
/**
* Remove a page for the given position. The adapter is responsible for
* removing the view from its container, although it only must ensure
* this is done by the time it returns from {#link #finishUpdate()}.
*
* #param container
* The containing View from which the page will be removed.
* #param position
* The page position to be removed.
* #param object
* The same object that was returned by
* {#link #instantiateItem(View, int)}.
*/
#Override
public void destroyItem(View collection, int position, Object view) {
pdfContainer.removeView((DocumentNewView) view);
}
/**
* Called when the a change in the shown pages has been completed. At
* this point you must ensure that all of the pages have actually been
* added or removed from the container as appropriate.
*
* #param container
* The containing View which is displaying this adapter's
* page views.
*/
#Override
public void finishUpdate(View arg0) {
CommonLogic.logMessage("Finish Update Called ", TAG, Log.VERBOSE);
}
#Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
}
#Override
public Parcelable saveState() {
return null;
}
#Override
public void startUpdate(View arg0) {
CommonLogic.logMessage("State Update Called ", TAG, Log.VERBOSE);
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((DocumentNewView) object);
}
Please give me any suggestions/changes in my code (if applicable) for it.
Thanks in Advance.
I could achieve this by overriding onPageSelected method of OnPageChangeListener. Consider you have three pages in this order A<->B<->C. To goal is to reach C if we scroll right from A and similarly to reach A if we scroll left from C.
To do this, define your to have 5 pages (3+2), and organize the pages as follows:
C<->A<->B<->C<->A
Now in the onPageSelected method, check and if position if 0, change it to 3 (getCount()-2) and if position is 4 (getCount()-1), change it to 1. Make sure to use the method:
setCurrentItem(item, smoothScroll)
Here is complete code for CircularPagerAdaptor Class :
package zolender.adapters;
import android.content.Context;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
public class CircularPagerAdapter extends PagerAdapter{
private int[] pageIDsArray;
private int count;
public CircularPagerAdapter(final ViewPager pager, int... pageIDs) {
super();
int actualNoOfIDs = pageIDs.length;
count = actualNoOfIDs + 2;
pageIDsArray = new int[count];
for (int i = 0; i < actualNoOfIDs; i++) {
pageIDsArray[i + 1] = pageIDs[i];
}
pageIDsArray[0] = pageIDs[actualNoOfIDs - 1];
pageIDsArray[count - 1] = pageIDs[0];
pager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
int pageCount = getCount();
if (position == 0){
pager.setCurrentItem(pageCount-2,false);
} else if (position == pageCount-1){
pager.setCurrentItem(1,false);
}
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// TODO Auto-generated method stub
}
#Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
}
});
}
public int getCount() {
return count;
}
public Object instantiateItem(View container, int position) {
LayoutInflater inflater = (LayoutInflater) container.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
int pageId = pageIDsArray[position];
View view = inflater.inflate(pageId, null);
((ViewPager) container).addView(view, 0);
return view;
}
#Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView((View) object);
}
#Override
public void finishUpdate(View container) {
// TODO Auto-generated method stub
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((View) object);
}
#Override
public void restoreState(Parcelable state, ClassLoader loader) {
// TODO Auto-generated method stub
}
#Override
public Parcelable saveState() {
// TODO Auto-generated method stub
return null;
}
#Override
public void startUpdate(View container) {
// TODO Auto-generated method stub
}
}
And here is how you can use it:
myPager = (ViewPager) findViewById(R.id.myfivepanelpager);
PagerAdapter adapter = new CircularPagerAdapter(myPager, new int[]{R.layout.farleft, R.layout.left, R.layout.middle, R.layout.right, R.layout.farright});
myPager.setAdapter(adapter);
myPager.setCurrentItem(3);
I also needed a circular ViewPager. This is what I've done. I assume you get pageCount value from somewhere.
...
pager = (ViewPager) findViewById(R.id.pager);
//Gesture detection
final GestureDetector gestureDetector = new GestureDetector(new MyGestureDetector());
pager.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
return gestureDetector.onTouchEvent(event);
}
});
//pagelistener is just for getting selected page
pager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
selectedPage = position;
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
and here is the GestureDetector.
Copied from here
class MyGestureDetector extends SimpleOnGestureListener {
#Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
int SWIPE_MIN_DISTANCE = Utils.ConvertToPixel(mContext, 50);
int SWIPE_MAX_OFF_PATH = Utils.ConvertToPixel(mContext, 250);
int SWIPE_THRESHOLD_VELOCITY = Utils.ConvertToPixel(mContext, 200);
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
return false;
// right to left swipe
if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY
&& selectedPage == (pageCount - 1)) {
pager.setCurrentItem(0);
return true;
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY
&& selectedPage == 0) {
pager.setCurrentItem(pageCount - 1);
return true;
}
} catch (Exception e) {
// nothing
}
return false;
}
}
Expanding on Z0lenDer's answer, when using a regular ViewPager where you don't need to free the memory for each associated view, it's more efficient to store the created views rather than the layout IDs. This is necessary if wanting to get rid of any delay and flicker when the item is being switched.
There's also an issue with the animation when using onPageSelected, as it doesn't let the slide finish before doing the switch. The only way I found to avoid this is to only perform the switch once the scroll state has changed to SCROLL_STATE_IDLE and just setting the current item in onPageSelected.
private int currentPage = 0;
...
pager.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
currentPage = position;
}
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
Log.d(TAG, "onPageScrollStateChanged: " + state);
if (state == ViewPager.SCROLL_STATE_IDLE) {
int pageCount = getCount();
if (currentPage == 0){
pager.setCurrentItem(pageCount-2,false);
} else if (currentPage == pageCount-1){
pager.setCurrentItem(1,false);
}
}
}
});
Try this
((ViewPager) container)
.setOnPageChangeListener(new OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
Log.i("TAG", "pos::" + position);
}
#Override
public void onPageScrollStateChanged(int state) {
// TODO Auto-generated method stub
int currentPage = pager.getCurrentItem();
Log.i("TAG", "currentPage::" + currentPage);
Log.i("TAG", "currentState::" + currentState);
Log.i("TAG", "previousState::" + previousState);
if (currentPage == 4 || currentPage == 0) {
previousState = currentState;
currentState = state;
if (previousState == 1 && currentState == 0) {
pager.setCurrentItem(currentPage == 0 ? 4 : 0);
}
}
}
#Override
public void onPageScrolled(int arg0, float arg1,
int arg2) {
// TODO Auto-generated method stub
}
});
return
This should be placed inside
#Override
public Object instantiateItem(final View container, int position) {}
I used it this way,
fragment layouts in adapter 0>1>2>3>4>5,
0 & 5 are dummy
viewPager.setAdapter(adapter);
viewPager.setCurrentItem(1, false); //going to page 1;
final int[] pagePosition = new int[1];
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
pagePosition[0] = position;
}
#Override
public void onPageScrollStateChanged(int state) { //state changes from 2 to 0 during a swipe
if (state == 0 && pagePosition[0] == 0){
viewPager.setCurrentItem(4, false);
} else if (state == 0 && pagePosition[0] == 5){
viewPager.setCurrentItem(1, false);
}
}
});
Well this helped
private class CircularViewPagerHandler implements ViewPager.OnPageChangeListener {
private ViewPager mViewPager;
private int mCurrentPosition;
private int mScrollState;
private int mPreviousPosition;
public CircularViewPagerHandler(final ViewPager viewPager) {
mViewPager = viewPager;
}
#Override
public void onPageSelected(final int position) {
mCurrentPosition = position;
mPreviousPosition = position-1;
}
#Override
public void onPageScrollStateChanged(final int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
setNextItemIfNeeded();
}
mScrollState = state;
}
private void setNextItemIfNeeded() {
if (!isScrollStateSettling()) {
handleSetNextItem();
}
}
private boolean isScrollStateSettling() {
return mScrollState == ViewPager.SCROLL_STATE_SETTLING; //indicated page is settling to it's final position
}
private void handleSetNextItem() {
final int lastPosition = mViewPager.getAdapter().getCount() - 1;
if (mCurrentPosition == 0) {
mViewPager.setCurrentItem(lastPosition,false);
} else if (mCurrentPosition == lastPosition) {
mViewPager.setCurrentItem(0, false);
}
}
#Override
public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) {
}
}
It was #tobi_b's answer

Categories

Resources