Centered View Pager with next and previous preview and pagetransformer

I am implementing a ViewPager that shows the next and previous elements, and also animates page transitions using ViewPager.PageTransformer. It has the effect of decreasing and decreasing brightness. To show the next and previous, I use negative PageMargin, padding on viewpager and clipToPadding as false. This is how it looks like

enter image description here

This is what I want. The problem is that PageTransform uses the left edge as a link, that is, it shows the maximum scale when the image touches the left edge, and not when it is in the center. To fix this, I used an offset in the code as follows

viewPager.setPageTransformer(false, new ViewPager.PageTransformer() { @Override public void transformPage(View page, float position) { if (position < -1) { page.setAlpha(0); } else if (position <= 1) { float scaleFactor = Math.max(0.7f, 1 - Math.abs(position - 0.14285715f)); page.setScaleX(scaleFactor); page.setScaleY(scaleFactor); page.setAlpha(scaleFactor); } else { page.setAlpha(0); } } }); 

I registered the position value when the image is in the center, and found the offset. But this offset only works on xxhdpi devices. In xxxhdpi, the value is 0.12068965f. Also, the offset changes when I change the padding to the ViewPager. In addition, the size of the preview of the next and previous changes using dpi.

Question

How can I calculate padding, margin and especially offset to maintain consistent behavior across different dpis?

code

Here is my layout where I add a viewpager and its addition

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="400dp" android:clipToPadding="false" android:paddingLeft="40dp" android:paddingRight="40dp"> </android.support.v4.view.ViewPager> <Button android:id="@+id/swiper" android:text="Animate" android:layout_centerInParent="true" android:layout_below="@id/viewPager" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout> 

Here is the viewpager initialization code:

 final ViewPager viewPager = ((ViewPager) findViewById(R.id.viewPager)); Resources r = getResources(); float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 120, r.getDisplayMetrics()); viewPager.setPageMargin((int) (-1 * px)); viewPager.setOffscreenPageLimit(5); 
+5
source share
1 answer

Here is what I ended up with:

 public class ZoomFadeTransformer implements ViewPager.PageTransformer { private float offset = -1; private float paddingLeft; private float minScale; private float minAlpha; public ZoomFadeTransformer(float paddingLeft, float minScale, float minAlpha) { this.paddingLeft = paddingLeft; this.minAlpha = minAlpha; this.minScale = minScale; } @Override public void transformPage(View page, float position) { if (offset == -1) { offset = paddingLeft / page.getMeasuredWidth(); } if (position < -1) { page.setAlpha(0); } else if (position <= 1) { float scaleFactor = Math.max(minScale, 1 - Math.abs(position - offset)); page.setScaleX(scaleFactor); page.setScaleY(scaleFactor); float alphaFactor = Math.max(minAlpha, 1 - Math.abs(position - offset)); page.setAlpha(alphaFactor); } else { page.setAlpha(0); } } } 

and I set it as

 viewPager.setPageTransformer(false, new ZoomFadeTransformer(viewPager.getPaddingLeft(), MIN_SCALE, MIN_ALPHA)); 
+2
source

Source: https://habr.com/ru/post/1239862/


All Articles