<!-- Copyright (c) 2012 Wireless Designs, LLC | |
Permission is hereby granted, free of charge, to any person obtaining | |
a copy of this software and associated documentation files (the | |
"Software"), to deal in the Software without restriction, including | |
without limitation the rights to use, copy, modify, merge, publish, | |
distribute, sublicense, and/or sell copies of the Software, and to | |
permit persons to whom the Software is furnished to do so, subject to | |
the following conditions: | |
The above copyright notice and this permission notice shall be | |
included in all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
--> | |
<?xml version="1.0" encoding="utf-8"?> | |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"> | |
<com.example.pagercontainer.PagerContainer | |
android:id="@+id/pager_container" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:background="#CCC"> | |
<android.support.v4.view.ViewPager | |
android:layout_width="150dp" | |
android:layout_height="100dp" | |
android:layout_gravity="center_horizontal" /> | |
</com.example.pagercontainer.PagerContainer> | |
</RelativeLayout> |
/* | |
* Copyright (c) 2012 Wireless Designs, LLC | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining | |
* a copy of this software and associated documentation files (the | |
* "Software"), to deal in the Software without restriction, including | |
* without limitation the rights to use, copy, modify, merge, publish, | |
* distribute, sublicense, and/or sell copies of the Software, and to | |
* permit persons to whom the Software is furnished to do so, subject to | |
* the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be | |
* included in all copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
*/ | |
package com.example.pagercontainer; | |
import android.app.Activity; | |
import android.graphics.Color; | |
import android.os.Bundle; | |
import android.support.v4.view.PagerAdapter; | |
import android.support.v4.view.ViewPager; | |
import android.view.Gravity; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.TextView; | |
/** | |
* PagerActivity: A Sample Activity for PagerContainer | |
*/ | |
public class PagerActivity extends Activity { | |
PagerContainer mContainer; | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.main); | |
mContainer = (PagerContainer) findViewById(R.id.pager_container); | |
ViewPager pager = mContainer.getViewPager(); | |
PagerAdapter adapter = new MyPagerAdapter(); | |
pager.setAdapter(adapter); | |
//Necessary or the pager will only have one extra page to show | |
// make this at least however many pages you can see | |
pager.setOffscreenPageLimit(adapter.getCount()); | |
//A little space between pages | |
pager.setPageMargin(15); | |
//If hardware acceleration is enabled, you should also remove | |
// clipping on the pager for its children. | |
pager.setClipChildren(false); | |
} | |
//Nothing special about this adapter, just throwing up colored views for demo | |
private class MyPagerAdapter extends PagerAdapter { | |
@Override | |
public Object instantiateItem(ViewGroup container, int position) { | |
TextView view = new TextView(PagerActivity.this); | |
view.setText("Item "+position); | |
view.setGravity(Gravity.CENTER); | |
view.setBackgroundColor(Color.argb(255, position * 50, position * 10, position * 50)); | |
container.addView(view); | |
return view; | |
} | |
@Override | |
public void destroyItem(ViewGroup container, int position, Object object) { | |
container.removeView((View)object); | |
} | |
@Override | |
public int getCount() { | |
return 5; | |
} | |
@Override | |
public boolean isViewFromObject(View view, Object object) { | |
return (view == object); | |
} | |
} | |
} |
/* | |
* Copyright (c) 2012 Wireless Designs, LLC | |
* | |
* Permission is hereby granted, free of charge, to any person obtaining | |
* a copy of this software and associated documentation files (the | |
* "Software"), to deal in the Software without restriction, including | |
* without limitation the rights to use, copy, modify, merge, publish, | |
* distribute, sublicense, and/or sell copies of the Software, and to | |
* permit persons to whom the Software is furnished to do so, subject to | |
* the following conditions: | |
* | |
* The above copyright notice and this permission notice shall be | |
* included in all copies or substantial portions of the Software. | |
* | |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
*/ | |
package com.example.pagercontainer; | |
import android.content.Context; | |
import android.graphics.Point; | |
import android.support.v4.view.ViewPager; | |
import android.util.AttributeSet; | |
import android.view.MotionEvent; | |
import android.widget.FrameLayout; | |
/** | |
* PagerContainer: A layout that displays a ViewPager with its children that are outside | |
* the typical pager bounds. | |
*/ | |
public class PagerContainer extends FrameLayout implements ViewPager.OnPageChangeListener { | |
private ViewPager mPager; | |
boolean mNeedsRedraw = false; | |
public PagerContainer(Context context) { | |
super(context); | |
init(); | |
} | |
public PagerContainer(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
init(); | |
} | |
public PagerContainer(Context context, AttributeSet attrs, int defStyle) { | |
super(context, attrs, defStyle); | |
init(); | |
} | |
private void init() { | |
//Disable clipping of children so non-selected pages are visible | |
setClipChildren(false); | |
//Child clipping doesn't work with hardware acceleration in Android 3.x/4.x | |
//You need to set this value here if using hardware acceleration in an | |
// application targeted at these releases. | |
setLayerType(View.LAYER_TYPE_SOFTWARE, null); | |
} | |
@Override | |
protected void onFinishInflate() { | |
try { | |
mPager = (ViewPager) getChildAt(0); | |
mPager.setOnPageChangeListener(this); | |
} catch (Exception e) { | |
throw new IllegalStateException("The root child of PagerContainer must be a ViewPager"); | |
} | |
} | |
public ViewPager getViewPager() { | |
return mPager; | |
} | |
private Point mCenter = new Point(); | |
private Point mInitialTouch = new Point(); | |
@Override | |
protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
mCenter.x = w / 2; | |
mCenter.y = h / 2; | |
} | |
@Override | |
public boolean onTouchEvent(MotionEvent ev) { | |
//We capture any touches not already handled by the ViewPager | |
// to implement scrolling from a touch outside the pager bounds. | |
switch (ev.getAction()) { | |
case MotionEvent.ACTION_DOWN: | |
mInitialTouch.x = (int)ev.getX(); | |
mInitialTouch.y = (int)ev.getY(); | |
default: | |
ev.offsetLocation(mCenter.x - mInitialTouch.x, mCenter.y - mInitialTouch.y); | |
break; | |
} | |
return mPager.dispatchTouchEvent(ev); | |
} | |
@Override | |
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { | |
//Force the container to redraw on scrolling. | |
//Without this the outer pages render initially and then stay static | |
if (mNeedsRedraw) invalidate(); | |
} | |
@Override | |
public void onPageSelected(int position) { } | |
@Override | |
public void onPageScrollStateChanged(int state) { | |
mNeedsRedraw = (state != ViewPager.SCROLL_STATE_IDLE); | |
} | |
} |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
Thesalan
commented
Aug 24, 2012
First, thanks for this code!! But I have some problem with it on some devices : HTC OneX (Android 4.0.4) and Nexus S (CM10 - Android 4.1.1). Otherwise, it works great on the emulator (tested with API 7 to 16) and older devices. My problem on these devices is that setClipChildren(false) doesn't work very well : just one item is shown by default (the current), and when you slide, just the current item and the next are shown. Have you got any ideas how to bypass this problem? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
devunwired
Aug 28, 2012
Looks like you've found a platform bug related to hardware acceleration (I found the Developer Groups thread). I've starred the issue at http://code.google.com/p/android/issues/detail?id=36788 and would recommend you do the same.
Looks like you've found a platform bug related to hardware acceleration (I found the Developer Groups thread). I've starred the issue at http://code.google.com/p/android/issues/detail?id=36788 and would recommend you do the same. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
Thesalan
Aug 28, 2012
Oh, I have not had time to inform you that you already know ;)
I've starred the issue too ;)
Thanks for your involvement!!
Thesalan
commented
Aug 28, 2012
Oh, I have not had time to inform you that you already know ;) I've starred the issue too ;) Thanks for your involvement!! |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
Bostwickenator
Sep 19, 2012
Looks great but I am getting some pretty odd behaviour with dragging the views. Jumping and sticking to the end views for instance. Anyone else noticed this?
Bostwickenator
commented
Sep 19, 2012
Looks great but I am getting some pretty odd behaviour with dragging the views. Jumping and sticking to the end views for instance. Anyone else noticed this? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
daedamr
Sep 24, 2012
What happens to me is that I have set the view pager to take 1/3 of the screen, and sometimes the outer pages stay in place and only the pager scrolls. I solved this by removing the condition for invalidate, so the view always invalidates on scroll:
@override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//Force the container to redraw on scrolling.
//Without this the outer pages render initially and then stay static
invalidate();
}
daedamr
commented
Sep 24, 2012
What happens to me is that I have set the view pager to take 1/3 of the screen, and sometimes the outer pages stay in place and only the pager scrolls. I solved this by removing the condition for invalidate, so the view always invalidates on scroll: |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
gdacarv
Nov 26, 2012
Hello, first of all: thank you! I'm trying to implement this and I have one small problem: On my nexus (4.1), if I touch the some no-focused view (any view at right or left of the currently selected view) it reacts like a click in my button in the selected view. I tested on Galaxi Mini (2.3) and this problem do not happens.
Anyone can help me?
gdacarv
commented
Nov 26, 2012
Hello, first of all: thank you! I'm trying to implement this and I have one small problem: On my nexus (4.1), if I touch the some no-focused view (any view at right or left of the currently selected view) it reacts like a click in my button in the selected view. I tested on Galaxi Mini (2.3) and this problem do not happens. Anyone can help me? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
magiccyril
Jan 21, 2013
Hello, I don't succeeded in using it with a FragmentPagerAdapter, is there something particular to do to make it work with Fragments ?
Thanks.
magiccyril
commented
Jan 21, 2013
Hello, I don't succeeded in using it with a FragmentPagerAdapter, is there something particular to do to make it work with Fragments ? Thanks. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
ghost
Jan 24, 2013
Thank you for your awesome code.but i have faced a problem when i want to use it Android 2.2 and 2.3.3.then shown the flowing method is applicable only Android API 11 or latter.
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
please let me know how to slove this issue?
Thanks.
ghost
commented
Jan 24, 2013
Thank you for your awesome code.but i have faced a problem when i want to use it Android 2.2 and 2.3.3.then shown the flowing method is applicable only Android API 11 or latter. setLayerType(View.LAYER_TYPE_SOFTWARE, null); please let me know how to slove this issue? Thanks. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
soarcn
Jan 31, 2013
@magiccyril simplely add an id for ViewPager would make it works for Fragment.
<android.support.v4.view.ViewPager
android:id="@+id/pager"
Tested in 4.1,works fine.
and because android 4 ViewPager has overscroll effect, it would be better to disable it in this case. using
pager.setOverScrollMode(View.OVER_SCROLL_NEVER);
soarcn
commented
Jan 31, 2013
@magiccyril simplely add an id for ViewPager would make it works for Fragment.
Tested in 4.1,works fine. and because android 4 ViewPager has overscroll effect, it would be better to disable it in this case. using |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
ferranpons
Jan 31, 2013
@coder015 you can bypass it using this:
if (Build.VERSION.SDK_INT >= 11)
{
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
ferranpons
commented
Jan 31, 2013
@coder015 you can bypass it using this: if (Build.VERSION.SDK_INT >= 11) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
tungdx
Feb 19, 2013
My viewpager has many item ( about 15 items), and I set mViewPager.setOffscreenPageLimit(6); and mViewPager.setCurrentItem(2); but when I run activity then see viewpager has 1 page in center is visible but page left, right are gone then I scroll viewpager ->page left and right are visible. I don't want that, I want page left and right visible immediately when activity run. How could i do?
tungdx
commented
Feb 19, 2013
My viewpager has many item ( about 15 items), and I set mViewPager.setOffscreenPageLimit(6); and mViewPager.setCurrentItem(2); but when I run activity then see viewpager has 1 page in center is visible but page left, right are gone then I scroll viewpager ->page left and right are visible. I don't want that, I want page left and right visible immediately when activity run. How could i do? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
guiguito
Apr 4, 2013
Overall a nice solution working well.
However, I tried to use it for hours on 2.X.
It worked only if i put a drawable as a background of my pages and not a color ! (even a drawable with only solid color was working better than a color set directly)
Dunno why ...
guiguito
commented
Apr 4, 2013
Overall a nice solution working well. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
swapniladsure
Apr 10, 2013
i want to provide custom image background for every image on list....as an example http://stackoverflow.com/questions/15925068/how-to-assign-background-container-for-horizontal-image-scroll-list
swapniladsure
commented
Apr 10, 2013
i want to provide custom image background for every image on list....as an example http://stackoverflow.com/questions/15925068/how-to-assign-background-container-for-horizontal-image-scroll-list |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
cesards
Apr 12, 2013
I think there is a problem. If we use pager.setOffscreenPageLimit(adapter.getCount());
How do we know the current page selected?
Well, I've looking for something, and I finally got the pagechangelistener, but we get into a problem if we use this:
pager.setOnPageChangeListener(this);
It doesn't work as expected. Do you know what's happening here?
Thanks!!
cesards
commented
Apr 12, 2013
I think there is a problem. If we use pager.setOffscreenPageLimit(adapter.getCount()); How do we know the current page selected? Well, I've looking for something, and I finally got the pagechangelistener, but we get into a problem if we use this: pager.setOnPageChangeListener(this); It doesn't work as expected. Do you know what's happening here? Thanks!! |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
cheezy64
May 3, 2013
First of all, very nice implementation! It's a very similar replacement for the Gallery widget.
I've implemented a PageTransformer to create a coverflow effect. It works for the most part, but at start up, it doesn't behave as expected. I can't force the clipped children to PageTransform programmatically.
"pager.setCurrentItem(n)" selects the nth item, but it doesn't trigger a "PageTransform".
"pager.invalidate()" which doesn't have an effect either.
Any ideas of how to trigger a PageTransform on the clipped children? I'm currently looking into fakeDrag() to see if it'll alleviate it
cheezy64
commented
May 3, 2013
First of all, very nice implementation! It's a very similar replacement for the Gallery widget. Any ideas of how to trigger a PageTransform on the clipped children? I'm currently looking into fakeDrag() to see if it'll alleviate it |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
cheezy64
commented
May 4, 2013
FYI, the fakeDrag commands work perfectly |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
chrisjenx
May 7, 2013
@m3n0r the Container
requires the setOnPageChangedListener, you need to add the implementation to the PagerContainer then delegate it through via the PagerContainer.
chrisjenx
commented
May 7, 2013
@m3n0r the |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
cesards
commented
Jun 19, 2013
@chrisjenx, yep, you were right, it was a pitty it was to late for me :P |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
fernandocamargoti
Jun 26, 2013
@cheezy64, have you implemented the coverflow effect? Can you open source it? Thank you.
fernandocamargoti
commented
Jun 26, 2013
@cheezy64, have you implemented the coverflow effect? Can you open source it? Thank you. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
nessusu
Jun 28, 2013
Fabulous work, I employed it in my test project and it behaves just what I expetecd except for one minor UI problem: there is a huge blank area at the start and end of ViewPager respectively. I dont want it.
I want the first page at the very left edge of the screen and after scrolling, the last page at the very right edge of the screen. Do you know how to eliminate the blank area?
the lightly tweaked main.xml is just as below:
<com.founder.gallery.PagerContainer
android:id="@+id/pager_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
android:background="@android:color/transparent" >
<android.support.v4.view.ViewPager
android:layout_width="284dp"
android:layout_height="238dp" />
</com.founder.gallery.PagerContainer>
nessusu
commented
Jun 28, 2013
Fabulous work, I employed it in my test project and it behaves just what I expetecd except for one minor UI problem: there is a huge blank area at the start and end of ViewPager respectively. I dont want it. I want the first page at the very left edge of the screen and after scrolling, the last page at the very right edge of the screen. Do you know how to eliminate the blank area? the lightly tweaked main.xml is just as below:
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
frankjoshua
Jul 22, 2013
Is there anyway to detect when a View other than the center View was touched? I want to allow the user to touch a view on the edge and have it become the selected view.
frankjoshua
commented
Jul 22, 2013
Is there anyway to detect when a View other than the center View was touched? I want to allow the user to touch a view on the edge and have it become the selected view. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
marckaraujo
commented
Sep 2, 2013
@frankjoshua, I have this problem too. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
marckaraujo
Sep 2, 2013
@frankjoshua, use this to invalidate pager scroll:
@Override
protected void onFinishInflate() {
try {
mPager = (ViewPager) getChildAt(0);
mPager.setOnPageChangeListener(this);
mPager.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
v.getParent().requestDisallowInterceptTouchEvent(true);
return false;
}
});
} catch (Exception e) {
throw new IllegalStateException("The root child of PagerContainer must be a ViewPager");
}
}
marckaraujo
commented
Sep 2, 2013
@frankjoshua, use this to invalidate pager scroll:
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
Rahulrsannidhi
Sep 11, 2013
hi ,its very helpful thanks,i created title bar for my application like tabs when i scroll the items its work fine but i need the current selected item i add onpagechangelistener issue is when i swipe the page the allocation of my tab is changing how it can fix .how i get current item please help
Rahulrsannidhi
commented
Sep 11, 2013
hi ,its very helpful thanks,i created title bar for my application like tabs when i scroll the items its work fine but i need the current selected item i add onpagechangelistener issue is when i swipe the page the allocation of my tab is changing how it can fix .how i get current item please help |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
egfconnor
Nov 19, 2013
Looks like it is fixed in Android KitKat 4.4. Changed my init to:
private void init() {
// Disable clipping of children so non-selected pages are visible
setClipChildren(false);
// Child clipping doesn't work with hardware acceleration in Android
// 3.x/4.x _BUT IS FIXED IN KIT KAT_
// You need to set this value here if using hardware acceleration in an
// application targeted at these releases.
if (Build.VERSION.SDK_INT < 19) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
Note my app is 4.0 and above so I just check if the sdk is less than 19.
egfconnor
commented
Nov 19, 2013
Looks like it is fixed in Android KitKat 4.4. Changed my init to: private void init() { |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
aat-antoine
Nov 26, 2013
Thanks, I've just discovered this class and it works as expected. Is there a way to have an infinite looper ?
aat-antoine
commented
Nov 26, 2013
Thanks, I've just discovered this class and it works as expected. Is there a way to have an infinite looper ? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
dmlukas
commented
Dec 5, 2013
Thank you. How to add images of different widths? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
Rufatet
Jan 8, 2014
Thank you. I liked it. And customized your code and used for my issues.
There are a problem: Have you tested below method with high int?
For example:
@override
public int getCount() {
return 100;
}
It is very slow :(
Know I work on improve speed as 6 (in your example).
If you tested please share your experience.
Best Regards.
Rufatet
commented
Jan 8, 2014
Thank you. I liked it. And customized your code and used for my issues. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
Rufatet
Jan 9, 2014
I applied pager.setPageTransformer(true, new ZoomOutPageTransformer()); So delayed. It looks cool, but speed awful. Do you have any idea improve it?
Rufatet
commented
Jan 9, 2014
I applied pager.setPageTransformer(true, new ZoomOutPageTransformer()); So delayed. It looks cool, but speed awful. Do you have any idea improve it? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
Rufatet
commented
Jan 9, 2014
I found :) |
loeschg
commented
Jan 17, 2014
@Rufatet, did you find any good performance tweaks? I'm not doing any transformations, and it's noticeably slower than a regular ViewPager. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
stefanahman
Feb 13, 2014
I have the problem with onClickLIsteners. Currently I show three (right, middle, left) ImageViews at the same time, and there are more items with higher indexes that are not visible at the time. The left item are overwritten as the right item, so when I click on the left, it says that the right are clicked. And also, when the first item is selected (left are empty), there is still a "hidden" item right there.
Update: Okey, the problem is that the left item till always have the same clicklistener as the right one. Think the override of onTouchEvent creates the problem.
stefanahman
commented
Feb 13, 2014
I have the problem with onClickLIsteners. Currently I show three (right, middle, left) ImageViews at the same time, and there are more items with higher indexes that are not visible at the time. The left item are overwritten as the right item, so when I click on the left, it says that the right are clicked. And also, when the first item is selected (left are empty), there is still a "hidden" item right there. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
akhr
commented
Apr 16, 2014
Hi devunwired, |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
mattsca
May 1, 2014
Hi,
I have an Android Tablet Asus, 10", with Android 4.2.1 and your code doesn't work. On Samsung S3 work correctly but on tablet the PageView fit exactly the central cell and the right and the left element don't move.
Can anyone help me?
Tnx:)
mattsca
commented
May 1, 2014
Hi, |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
MicheleDB
Jun 5, 2014
Works well as a replacement for Gallery except for determining what items is "clicked". Has anybody implemented an onClickListener? the example shows onPageSelected which is not suitable since it "fires up" on any scroll before you can decide what to click. Please supply example.
MicheleDB
commented
Jun 5, 2014
Works well as a replacement for Gallery except for determining what items is "clicked". Has anybody implemented an onClickListener? the example shows onPageSelected which is not suitable since it "fires up" on any scroll before you can decide what to click. Please supply example. |
gavelez
commented
Jun 5, 2014
@nessusu did you find any solution to your issue? It will be very helpful if you did it. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
ggilrong
commented
Jul 30, 2014
Thanks you!! |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
malinkang
commented
Aug 16, 2014
Thanks you!! |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
marcospaulo
Aug 21, 2014
I still have a problem with setOnClickListener for the pages. I want to be able to click on a page and drag the other view pager. But it's not working, it's always calling the setOnClickListener from the right. page. Anyone with the same problem? Did someone find a solution?
I saw some old comments like the one from @frankjoshua and @marckaraujo with the same problem, but I didnt see any solution for it.
Thank you in advance.
marcospaulo
commented
Aug 21, 2014
I still have a problem with setOnClickListener for the pages. I want to be able to click on a page and drag the other view pager. But it's not working, it's always calling the setOnClickListener from the right. page. Anyone with the same problem? Did someone find a solution? I saw some old comments like the one from @frankjoshua and @marckaraujo with the same problem, but I didnt see any solution for it. Thank you in advance. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
traninho
commented
Nov 4, 2014
Has anyone solved on click events on the edge items? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
psparago
Nov 22, 2014
First off, thank you very much for posting this code, Dave.
Without going into detail about my ViewPager implementation, the PagerContainer works as expected on my KitKat (4.4.2) tablet, but not on my other 2 Jelly Bean tablets (4.2.2). On Jelly Bean, I'm getting the behavior where the "outer" pages stay static. This is the behavior that the invalidate() call in onPageScrolled is supposed to fix. Has anyone else experienced this? Is there a workaround?
psparago
commented
Nov 22, 2014
First off, thank you very much for posting this code, Dave. Without going into detail about my ViewPager implementation, the PagerContainer works as expected on my KitKat (4.4.2) tablet, but not on my other 2 Jelly Bean tablets (4.2.2). On Jelly Bean, I'm getting the behavior where the "outer" pages stay static. This is the behavior that the invalidate() call in onPageScrolled is supposed to fix. Has anyone else experienced this? Is there a workaround? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
scottmeng
Jan 2, 2015
I used a simple trick to block on click event from getting fired up when tapping on edge items.
Below is the helper function I added to PagerContainer
class
private boolean isInNonTappableRegion(float oldX, float newX) {
int tappableWidth = mPager.getWidth();
int totalWidth = getWidth();
if (oldX < (totalWidth - tappableWidth) / 2 && newX < (totalWidth - tappableWidth) / 2) {
return true;
}
if (oldX > (totalWidth + tappableWidth) / 2 && newX > (totalWidth + tappableWidth) / 2) {
return true;
}
return false;
}
I also modified its onTouchEvent
handler:
@Override
public boolean onTouchEvent(MotionEvent ev) {
//We capture any touches not already handled by the ViewPager
// to implement scrolling from a touch outside the pager bounds.
switch (ev.getAction()) {
// if tapping happens on edge items
case MotionEvent.ACTION_UP:
if (isInNonTappableRegion(mInitialTouch.x, ev.getX())) {
ev.setAction(MotionEvent.ACTION_CANCEL);
}
ev.offsetLocation(mCenter.x - mInitialTouch.x, mCenter.y - mInitialTouch.y);
break;
case MotionEvent.ACTION_DOWN:
mInitialTouch.x = (int)ev.getX();
mInitialTouch.y = (int)ev.getY();
default:
ev.offsetLocation(mCenter.x - mInitialTouch.x, mCenter.y - mInitialTouch.y);
break;
}
return mPager.dispatchTouchEvent(ev);
}
scottmeng
commented
Jan 2, 2015
I used a simple trick to block on click event from getting fired up when tapping on edge items. Below is the helper function I added to
I also modified its
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
bblackbelt
Jan 12, 2015
Hi all, and thanks for sharing your code. Did somebody managed to make the onClick behave like the gallery?, making the clicked item move to the central position?
bblackbelt
commented
Jan 12, 2015
Hi all, and thanks for sharing your code. Did somebody managed to make the onClick behave like the gallery?, making the clicked item move to the central position? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
worawees
Jan 20, 2015
The modified version of @scottmeng, which will return the delta item position should be changed from the current item of the pager.
deltaPosition == 0 click on tappable area
deltaPosition != 0 click on non-tappable area
We can use this value to do 2 things
- set currentItem to the new position (pager.setCurrentItem(pager.getCurrentItem() + daltaPosition)
- activate on item click action, with the right data item index
private int isInNonTappableRegion(float oldX, float newX) {
int tappableWidth = mPager.getWidth();
int totalWidth = getWidth();
int nonTappableWidth = (totalWidth - tappableWidth) / 2;
if (oldX < nonTappableWidth && newX < nonTappableWidth) {
return -(int) Math.ceil((nonTappableWidth - newX) / (float) tappableWidth);
}
nonTappableWidth = (totalWidth + tappableWidth) / 2;
if (oldX > nonTappableWidth && newX > nonTappableWidth) {
return (int) Math.ceil((newX - nonTappableWidth) / (float) tappableWidth);
}
return 0;
}
worawees
commented
Jan 20, 2015
The modified version of @scottmeng, which will return the delta item position should be changed from the current item of the pager. We can use this value to do 2 things
private int isInNonTappableRegion(float oldX, float newX) {
int tappableWidth = mPager.getWidth();
int totalWidth = getWidth();
int nonTappableWidth = (totalWidth - tappableWidth) / 2;
if (oldX < nonTappableWidth && newX < nonTappableWidth) {
return -(int) Math.ceil((nonTappableWidth - newX) / (float) tappableWidth);
}
nonTappableWidth = (totalWidth + tappableWidth) / 2;
if (oldX > nonTappableWidth && newX > nonTappableWidth) {
return (int) Math.ceil((newX - nonTappableWidth) / (float) tappableWidth);
}
return 0;
} |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
MitchDroid
Mar 3, 2015
Hi @worawees, I saw your modified version of @scottmeng, but could you tell me how or where I can implement this method isInNonTappableRegion()? in @scottmeng method it returns a boolean but in your methos it return an int and I don´t know how to use it.
Thanks for your help.
Regards.
MitchDroid
commented
Mar 3, 2015
Hi @worawees, I saw your modified version of @scottmeng, but could you tell me how or where I can implement this method isInNonTappableRegion()? in @scottmeng method it returns a boolean but in your methos it return an int and I don´t know how to use it. Thanks for your help. Regards. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
FaizanMubasher
Apr 16, 2015
Is there any way to implement it Vertically? I have to show it in Landscape mod but it shouldn't take whole screen.
FaizanMubasher
commented
Apr 16, 2015
Is there any way to implement it Vertically? I have to show it in Landscape mod but it shouldn't take whole screen. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
lemartva
commented
Apr 22, 2015
Thank you! |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
forsubhi
May 29, 2015
click left item cause clicking the right one of nexus 7, why?
I saw some old comments like the one from @frankjoshua,@marcospauloand and @marckaraujo with the same problem, but I didnt see any solution for it.
forsubhi
commented
May 29, 2015
click left item cause clicking the right one of nexus 7, why? I saw some old comments like the one from @frankjoshua,@marcospauloand and @marckaraujo with the same problem, but I didnt see any solution for it. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
lysrt
Aug 1, 2015
Hi @MitchDroid,
You can use @worawees code this way:
@Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
int delta = isInNonTappableRegion(mInitialTouch.x, ev.getX());
if (delta != 0) {
ev.setAction(MotionEvent.ACTION_CANCEL);
mPager.setCurrentItem(mPager.getCurrentItem() + delta );
}
ev.offsetLocation(mCenter.x - mInitialTouch.x, mCenter.y - mInitialTouch.y);
break;
...
A click on a side item will bring it to the center, and it works like a charm :)
lysrt
commented
Aug 1, 2015
Hi @MitchDroid, You can use @worawees code this way: @Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_UP:
int delta = isInNonTappableRegion(mInitialTouch.x, ev.getX());
if (delta != 0) {
ev.setAction(MotionEvent.ACTION_CANCEL);
mPager.setCurrentItem(mPager.getCurrentItem() + delta );
}
ev.offsetLocation(mCenter.x - mInitialTouch.x, mCenter.y - mInitialTouch.y);
break;
...
A click on a side item will bring it to the center, and it works like a charm :) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
amitprabhudesai
Aug 25, 2015
@nessusu The blank area is because the ViewPager
gravity is set as center_horizontal
. To fix this, you will need to set the gravity to start
for the first page, end
for the last page. To do this you can update the layout params for the ViewPager
in the onPageSelected
event.
Something like so:
@Override
public void onPageSelected(int position) {
FrameLayout.LayoutParams viewPagerLayoutParams
= (FrameLayout.LayoutParams) viewPager.getLayoutParams();
if (0 == position) {
viewPagerLayoutParams.gravity = Gravity.START;
} else if (getNumItemsInScrollableContainer()-1 == position) {
viewPagerLayoutParams.gravity = Gravity.END;
} else {
viewPagerLayoutParams.gravity = Gravity.CENTER_HORIZONTAL;
}
viewPager.requestLayout();
}
HTH.
amitprabhudesai
commented
Aug 25, 2015
@nessusu The blank area is because the
HTH. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
fr-al
commented
Oct 20, 2015
It's working just great! Thanks. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
yarolegovich
Dec 20, 2015
Hi, when I use this solution with PagerTransformer - views inside viewpager are not updated until page is scrolled. Any advices on how can I solve it?
yarolegovich
commented
Dec 20, 2015
Hi, when I use this solution with PagerTransformer - views inside viewpager are not updated until page is scrolled. Any advices on how can I solve it? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
openkwaky
commented
Jan 29, 2016
Same problem as yarolegovich. Any clue ? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
alin-rosu
Feb 12, 2016
How can I change the text of the selected page?
I added a OnPageChangeListener, but how can I access the textview from my selection, and also the others?
alin-rosu
commented
Feb 12, 2016
How can I change the text of the selected page? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
ghost
Mar 9, 2016
thank you for your code but there is problem in PagerContainer
protected void onFinishInflate() needs Overriding method should call super
can anyone explain this?
ghost
commented
Mar 9, 2016
thank you for your code but there is problem in PagerContainer protected void onFinishInflate() needs Overriding method should call super can anyone explain this? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
MrThiago
Jul 21, 2016
Thanks guys for this.
Is there a way to make the next item and the preview item blurred, then when on focus remove the blur ?
thanks
MrThiago
commented
Jul 21, 2016
Thanks guys for this. Is there a way to make the next item and the preview item blurred, then when on focus remove the blur ? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
gSrikar
Jul 25, 2016
@boshraviva Did you called super.onFinishInflate()? and did you figured out What it does?
gSrikar
commented
Jul 25, 2016
@boshraviva Did you called super.onFinishInflate()? and did you figured out What it does? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
MrThiago
commented
Aug 25, 2016
Which method is this getNumItemsInScrollableContainer() ? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
MrThiago
Aug 25, 2016
Guys, I have a problem.
I have 3 items visible.
If I select the 3rd item it will return item on 2nd position.
Do you guys have this problem?
MrThiago
commented
Aug 25, 2016
Guys, I have a problem. I have 3 items visible. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
princerk
commented
Nov 24, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
adityasd
Jan 5, 2017
I used two viewpager..in first pager i have only images of product. now if user swipe image from pager 1 then in pager 2 i want to set its different prices..how to do that can any one help?
http://stackoverflow.com/questions/41217237/viewpager-not-getting-last-item
adityasd
commented
Jan 5, 2017
I used two viewpager..in first pager i have only images of product. now if user swipe image from pager 1 then in pager 2 i want to set its different prices..how to do that can any one help? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Show comment Hide comment
jimitpatel
Jan 11, 2017
@princerk I am also wondering same. Was checking this code, and surprisingly it is not working for me at all.
@devunwired is there any updates on this code you made. Code seems workable but still it's not working in my scenario. I have ViewPager
inside RecyclerView
. So I have to use wrap_content
for ViewPager
. And have made customization in onMeasure
to get wrapped content. Then I used your piece of code for getting preview of previous and next view. Unfortunately I am not getting it. I don't know what I am missing. I will give CustomViewPager
code over here. In that there is also vertical swipe related code, but that is what I am not using in the discussed scenario. Just wrapping the height. isWrap
is true in below code
/**
* Created by Jimit Patel on 29/07/15.
*/
public class CustomViewPager extends ViewPager {
private static final String TAG = CustomViewPager.class.getSimpleName();
public static final int HORIZONTAL = 0;
public static final int VERTICAL = 1;
public static final int NONE = 0;
public static final int HEIGHT = 1;
public static final int WIDTH = 2;
private boolean isPagingEnabled, isSwipeable, isSquare, isWrap;
private int mSwipeOrientation;
private ScrollerCustomDuration mScroller = null;
private double heightRatio, widthRatio;
private int mCalculationType;
private View mCurrentView;
public CustomViewPager(Context context) {
super(context);
this.isPagingEnabled = true;
this.isSwipeable = true;
isSquare = false;
mCalculationType = NONE;
heightRatio = 0;
widthRatio = 0;
mSwipeOrientation = HORIZONTAL;
postInitViewPager();
}
public CustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
setIsSquare(context, attrs);
setDimensionRatio(context, attrs);
setSwipeOrientation(context, attrs);
this.isPagingEnabled = true;
this.isSwipeable = true;
postInitViewPager();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!this.isPagingEnabled || !this.isSwipeable)
return false;
return super.onTouchEvent(mSwipeOrientation == VERTICAL ? swapXY(event) : event);
}
@Override
public boolean onInterceptHoverEvent(MotionEvent event) {
// return super.onInterceptHoverEvent(event);
return false;
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (!this.isPagingEnabled || !this.isSwipeable)
return false;
else if (mSwipeOrientation == VERTICAL) {
boolean intercepted = super.onInterceptHoverEvent(swapXY(event));
swapXY(event);
return intercepted;
}
return super.onInterceptTouchEvent(event);
}
public void setPagingEnabled(boolean isPagingEnabled) {
this.isPagingEnabled = isPagingEnabled;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
boolean isDefault;
int width, height;
switch (mCalculationType) {
case WIDTH: {
isDefault = false;
height = MeasureSpec.getSize(heightMeasureSpec);
width = (int) ((float) (((float) (heightRatio > 0 ? heightRatio : 1) / (float) (widthRatio > 0 ? widthRatio : 1)) * height));
break;
}
case HEIGHT: {
isDefault = false;
width = MeasureSpec.getSize(widthMeasureSpec);
height = (int) ((float) (((float) (widthRatio > 0 ? widthRatio : 1) / (float) (heightRatio > 0 ? heightRatio : 1)) * width));
break;
}
default: {
isDefault = true;
width = widthMeasureSpec;
height = heightMeasureSpec;
break;
}
}
if (!isDefault) {
setMeasuredDimension(width, height);
measureChildren(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), (isSquare
? MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY) : MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)));
} else {
if (!isSquare && isWrap) {
if (mCurrentView == null) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
height = 0;
mCurrentView.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = mCurrentView.getMeasuredHeight();
if (h > height) height = h;
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
} else {
super.onMeasure(widthMeasureSpec, isSquare ? widthMeasureSpec : heightMeasureSpec);
}
}
}
public void measureCurrentView(View currentView) {
mCurrentView = currentView;
requestLayout();
}
public void setSwipeOrientation(int swipeOrientation) {
if (swipeOrientation == HORIZONTAL || swipeOrientation == VERTICAL)
mSwipeOrientation = swipeOrientation;
else
throw new IllegalStateException("Swipe Orientation can be either CustomViewPager.HORIZONTAL" +
" or CustomViewPager.VERTICAL");
initSwipeMethods();
}
private void setIsSquare(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SquareViewPager);
boolean isSquare = typedArray.getBoolean(R.styleable.SquareViewPager_square_dimens, false);
setIsSquare(isSquare);
typedArray.recycle();
}
private void setSwipeOrientation(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomViewPager);
mSwipeOrientation = typedArray.getInteger(R.styleable.CustomViewPager_swipe_orientation, 0);
typedArray.recycle();
initSwipeMethods();
}
private void setDimensionRatio(Context context, AttributeSet attrs) {
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SquareViewPager);
int ratioWidth = typedArray.getInteger(R.styleable.SquareViewPager_width_ratio, 0);
int ratioHeight = typedArray.getInteger(R.styleable.SquareViewPager_height_ratio, 0);
int calculationType = typedArray.getInteger(R.styleable.SquareViewPager_calculation, 0);
setDimensionRatio(ratioWidth, ratioHeight, calculationType);
typedArray.recycle();
}
private void setDimensionRatio(int ratioWidth, int ratioHeight, int calculationType) {
this.widthRatio = ratioWidth;
this.heightRatio = ratioHeight;
this.mCalculationType = calculationType;
}
public void setIsSquare(boolean isSquare) {
this.isSquare = isSquare;
}
public void setHeightRatio(double heightRatio) {
this.heightRatio = heightRatio;
}
public void setWidthRatio(double widthRatio) {
this.widthRatio = widthRatio;
}
public boolean isSquare() {
return this.isSquare;
}
public boolean isWrap() {
return isWrap;
}
public void setWrap(boolean wrap) {
isWrap = wrap;
}
public void setSwipeEnabled(boolean isSwipeable) {
this.isSwipeable = isSwipeable;
}
/**
* Override the Scroller instance with our own class so we can change the
* duration
*/
private void postInitViewPager() {
try {
Field scroller = ViewPager.class.getDeclaredField("mScroller");
scroller.setAccessible(true);
Field interpolator = ViewPager.class.getDeclaredField("sInterpolator");
interpolator.setAccessible(true);
mScroller = new ScrollerCustomDuration(getContext(),
(Interpolator) interpolator.get(null));
scroller.set(this, mScroller);
} catch (Exception e) {
}
}
private void initSwipeMethods() {
if (mSwipeOrientation == VERTICAL) {
// The majority of the work is done over here
setPageTransformer(true, new VerticalPageTransformer());
// The easiest way to get rid of the overscroll drawing that happens on the left and right
setOverScrollMode(OVER_SCROLL_NEVER);
}
}
/**
* Set the factor by which the duration will change
*/
public void setScrollDurationFactor(double scrollFactor) {
mScroller.setScrollDurationFactor(scrollFactor);
}
public int measureFragment(View view) {
if (view == null)
return 0;
view.measure(0, 0);
return view.getMeasuredHeight();
}
/**
* Determines the height of this view
*
* @param measureSpec A measureSpec packed into an int
* @param view the base view with already measured height
* @return The height of the view, honoring constraints from measureSpec
*/
private int measureHeight(int measureSpec, View view) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
// set the height from the base view if available
if (view != null) {
result = view.getMeasuredHeight();
}
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
/**
* Determines the width of this view
*
* @param measureSpec A measureSpec packed into an int
* @param view the base view with already measured width
* @return The height of the view, honoring constraints from measureSpec
*/
private int measureWidth(int measureSpec, View view) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
// set the height from the base view if available
if (view != null) {
result = view.getMeasuredWidth();
}
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
private MotionEvent swapXY(MotionEvent event) {
float width = getWidth();
float height = getHeight();
float newX = (event.getY() / height) * width;
float newY = (event.getX() / width) * height;
event.setLocation(newX, newY);
return event;
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
@Override
public void transformPage(View page, float position) {
if (position < -1) {
// This page is way off-screen to the left
page.setAlpha(0);
} else if (position <= 1) {
page.setAlpha(1);
// Counteract the default slide transition
page.setTranslationX(page.getWidth() * -position);
// set Y position to swipe in from top
float yPosition = position * page.getHeight();
page.setTranslationY(yPosition);
} else {
// This page is way off screen to the right
page.setAlpha(0);
}
}
}
}
And in PagerAdapter
, I am using this piece of code to get measurement
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
if (position != mCurrentPosition) {
View view = (View) object;
CustomViewPager pager = (CustomViewPager) container;
if (null != view) {
mCurrentPosition = position;
pager.measureCurrentView(view);
}
}
jimitpatel
commented
Jan 11, 2017
•
edited
edited
@princerk I am also wondering same. Was checking this code, and surprisingly it is not working for me at all. @devunwired is there any updates on this code you made. Code seems workable but still it's not working in my scenario. I have
And in
|
First, thanks for this code!!
But I have some problem with it on some devices : HTC OneX (Android 4.0.4) and Nexus S (CM10 - Android 4.1.1). Otherwise, it works great on the emulator (tested with API 7 to 16) and older devices.
My problem on these devices is that setClipChildren(false) doesn't work very well : just one item is shown by default (the current), and when you slide, just the current item and the next are shown.
Have you got any ideas how to bypass this problem?