I am implementing a ViewPager which shows next and previous items and also animates page transitions using ViewPager.PageTransformer. It has a zoom out and fade out effect. For showing next and previous, I am using negative PageMargin, padding on viewpager and clipToPadding as false. This is how it looks like
Which is what I want. The problem is that PageTransform uses left edge as the reference i.e. it shows maximum zoom when image touches left edge instead of when it is in 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 logged the position value when image is in center and found the offset. But this offset only works on xxhdpi devices. On xxxhdpi, value comes out to be 0.12068965f. Also, the offset changes when I change the padding on ViewPager. Also, the preview size of next and previous changes with dpi.
Question
How can I calculate the padding, margin and especially offset to keep consistent behaviour across different dpis?
Code
Here is my layout where I am adding viewpager and its padding
<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 initialisation 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);
ViewPager in Android allows the user to flip left and right through pages of data. In our android ViewPager application we'll implement a ViewPager that swipes through three views with different images and texts.
So a Viewpager is an android widget that is used to navigate from one page to another page by swiping left or right using the same activity. So when we use Viewpager, we can add different layouts in one activity and this can be done by using the fragments.
Steps for implementing viewpager: Adding the ViewPager widget to the XML layout (usually the main_layout). Creating an Adapter by extending the FragmentPagerAdapter or FragmentStatePagerAdapter class.
This 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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With