/PagerActivity.java Secret
-
Star
(263)
You must be signed in to star a gist -
Fork
(86)
You must be signed in to fork a gist
-
-
Save devunwired/8cbe094bb7a783e37ad1 to your computer and use it in GitHub Desktop.
| <!-- 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); | |
| } | |
| } |
Which method is this getNumItemsInScrollableContainer() ?
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?
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
@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);
}
}



@boshraViva Did you called super.onFinishInflate()? and did you figured out What it does?