In vertical viewpager, while swipe in vertically current screen are move to left side but i have to move my second view over the first view (i.e)first view should be fit to the screen.I had implement the vertical stack transformer but its not working fine to me. Can you anyone help me to fix this issue.
Thanks in advance.
This is viewpager I had used.
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setPageTransformer(true, new VerticalPageTransformer());
setOverScrollMode(OVER_SCROLL_NEVER);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // (0,1]
// Counteract the default slide transition
view.setTranslationY(position < 0 ? 0f : -view.getHeight() * position);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
try {
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
Here my code I had modified.
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // (0,1]
// Counteract the default slide transition
view.setTranslationY(position < 0 ? 0f : -view.getHeight() * position);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
Related
I wanted to make a Vertical ViewPager looklike inshorts application.
I have tried several solutions found on Stack Overflow and in Github.
All of them have the same way of implementation of code, and all of them have the same lagging issue while scrolling up and down(vertical scroll), you can see in the video, but the design implementation is same as inshorts.
The link which I have tried are,
1) VerticalViewPager
2) DirectionViewPager
3) Github Repos
I have also tried for mFlingDistance,mMinimumVelocity etc from android's Viewpager class for increasing fling in Viewpager. But with no luck of making it working.
Below is my VerticalViewPager class
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens 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);
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
And using VerticaPageTransformer class for page transition.
class VerticalPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // [0,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
The one that worked for me was of castorflex solution for smooth scrolling, but when I apply a PageTransformer to castorflex solution, instead of scrolling vertically is scroll diagonally.You can see the reference video here.
I have also tried with ViewPager2 and with RecyclerView(with SnapHelper) but with viewpager2, I am getting the same diagonal issue. And with Snaphelper, I am unable to provide a page effect like inshorts(see the videos). May be, it will be possible by LinearLayoutManager of RecyclerView, as I have seen here. But failed to convert my page animation.
So anyone can give me any hint, or any idea about
1) How to make smooth scrolling with above approach? or
2) How to make vertical page transition from below approach, instead of diagonal? or
3) Or any other way if you people have.
Thanks in advance
You can see Castorflex's VerticalViewPager class, and using the same VerticlePageTransform class for page transformation
Check this Github Repo https://github.com/dipanshukr/Viewpager-Transformation
SampleActivity.java
private void initViewPager() {
VerticalViewPager viewPager = (VerticalViewPager) findViewById(R.id.vertical_viewpager);
//viewPager.setPageTransformer(false, new ZoomOutTransformer());
//viewPager.setPageTransformer(true, new StackTransformer());
String title = "ContentFragment";
viewPager.setAdapter(new ContentFragmentAdapter.Holder(getSupportFragmentManager())
.add(ContentFragment.newInstance(title, 1))
.add(ContentFragment.newInstance(title, 2))
.add(ContentFragment.newInstance(title, 3))
.add(ContentFragment.newInstance(title, 4))
.add(ContentFragment.newInstance(title, 5))
.set());
// If you setting other scroll mode,
// the scrolled fade is shown from either side of display.
viewPager.setOverScrollMode(View.OVER_SCROLL_NEVER);
}
VerticalViewPager.java
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
this(context, null);
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
setPageTransformer(false, new DefaultTransformer());
}
private MotionEvent swapTouchEvent(MotionEvent event) {
float width = getWidth();
float height = getHeight();
float swappedX = (event.getY() / height) * width;
float swappedY = (event.getX() / width) * height;
event.setLocation(swappedX, swappedY);
return event;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent event) {
boolean intercept = super.onInterceptTouchEvent(swapTouchEvent(event));
//If not intercept, touch event should not be swapped.
swapTouchEvent(event);
return intercept;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapTouchEvent(ev));
}
}
DefaultTransformer.java
public class DefaultTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
float alpha = 0;
if (0 <= position && position <= 1) {
alpha = 1 - position;
} else if (-1 < position && position < 0) {
alpha = position + 1;
}
view.setAlpha(alpha);
view.setTranslationX(view.getWidth() * -position);
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
}
}
I need to implement a viewpager that can do both horizontal and vertical paging. If the user switches the page vertically, a vertical PageTransformer should carry out the animation. Otherwise, the regular animation should happen.
I found a couple of libraries that attempt to solve this problem, but they run into problems when one of the views has a ScrollView inside.
If it's possible, I would like to implement it without third party libaries.
So far, all I have is the code for a vertical viewpager, but I can't figure out how to add the horizontal functionality as well:
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens 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);
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
Just for reference, this is the my vertical PageTransformer:
public class VerticalPageTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
Any help would be appreciated
So here's the deal:
I have a custom ViewPager with a Camera Preview fragment and another page, both work fine on their own. The transition between the two makes the camera turn white instead of just maintaining the view. I used a modification to make it a Vertical view pager instead of horizontal.
Before it was vertical, the stock view pager worked just fine. Here's what it looked like before: http://i.imgur.com/eaaHGvR.gif
And now:
http://i.imgur.com/RKxiYZL.gif
What did I miss that's making it go white?
Custom View Pager:
public class VerticalPager extends ViewPager {
public VerticalPager(Context context) {
super(context);
init();
}
public VerticalPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens 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);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
//view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
//view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
//view.setAlpha(0);
}
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
EDIT:
After some tinkering, I got closer, but still crazy amounts of flickering and bugs. Previously, on the horizontal, it had some edge-issues but did not flicker like this:
http://i.imgur.com/aBcreT9.gif
I added view.BringToFront(); in the verticalpager, and also requested transparency when I set the adapter on the pager itself.
I am very new to android ,i trying to implement vertical view pager with zoom out page transformer my vertical view pager working fine when i come for zoomout page transformer it will scroll horizontally ,it was not scrolling vertically
my vertical view pager class
VerticalViewPager.class
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens 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);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
my zoomout animation class
AnimationViewPager.class
public class AnimationViewPager implements VerticalViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
here my sample image i am trying to like this,please any one help me how to get this
firstly use this lib. it's the most closet to the out of box one ,
link given below
github.com/castorflex/VerticalViewPager
then create a new class
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
in your mainactivity class, set the animation on verticalviewpager class like this
verticalViewPager=(VerticalViewPager)findViewById(R.id.verticalview);
verticalViewPager.setPageTransformer(false,new DepthPageTransformer());
verticalViewPager.setAdapter(pager);
that's it, thank you and please rate my answer :)
I have a custom vertical view pager that extends view pager. now i want to include pagerTabStrip. Now the thing is it can be align either on top or bottom. But for this customized viewpager i need vertical pagertabstrip as the pages/fragments scrolls verticall.
Here is the code of VerticalViewPager
public class VerticalViewPager extends ViewPager {
public VerticalViewPager(Context context) {
super(context);
init();
}
public VerticalViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
// The majority of the magic happens 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);
}
private class VerticalPageTransformer implements ViewPager.PageTransformer {
#Override
public void transformPage(View view, float position) {
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 1) { // [-1,1]
view.setAlpha(1);
// Counteract the default slide transition
view.setTranslationX(view.getWidth() * -position);
//set Y position to swipe in from top
float yPosition = position * view.getHeight();
view.setTranslationY(yPosition);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
/**
* Swaps the X and Y coordinates of your touch event.
*/
private MotionEvent swapXY(MotionEvent ev) {
float width = getWidth();
float height = getHeight();
float newX = (ev.getY() / height) * width;
float newY = (ev.getX() / width) * height;
ev.setLocation(newX, newY);
return ev;
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev){
boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
swapXY(ev); // return touch coordinates to original reference frame for any child views
return intercepted;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
return super.onTouchEvent(swapXY(ev));
}
}
The Xml for the VewPager is
<com.mypackage.customViews.VerticalViewPager
android:id="#+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="20dp"
android:scrollIndicators="top"
>
<android.support.v4.view.PagerTabStrip
android:id="#+id/pager_title_strip"
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout_gravity="right"
android:paddingBottom="#dimen/padding8"
android:paddingTop="#dimen/padding8"
android:textColor="#color/link_color" />
</com.TCYonline.android.BetterThink.customViews.VerticalViewPager>
Please help me out.