具有下一个和上一个预览和 pagetransformer 的居中视图寻呼机
Centered View Pager with next and previous preview and pagetransformer
我正在实现一个 ViewPager,它显示下一个和上一个项目,还使用 ViewPager.PageTransformer 动画页面转换。它具有缩小和淡出效果。为了显示下一个和上一个,我使用负 PageMargin,viewpager 上的填充和 clipToPadding 为 false。这是它的样子
这就是我想要的。问题在于 PageTransform 使用左边缘作为参考,即当图像接触左边缘而不是位于中心时它显示最大缩放。为了解决这个问题,我在代码中使用了一个偏移量,如下所示
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);
}
}
});
我记录了图像居中时的位置值并找到了偏移量。但此偏移量仅适用于 xxhdpi 设备。在 xxxhdpi 上,值为 0.12068965f。此外,当我更改 ViewPager 上的填充时,偏移量也会发生变化。此外,下一个和上一个的预览大小随 dpi 变化。
问题
如何计算填充、边距,尤其是偏移量以在不同 dpis 之间保持一致的行为?
代码
这是我添加 viewpager 及其填充的布局
<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>
这里是viewpager的初始化代码:
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);
这就是我最终得到的结果:
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);
}
}
}
我把它设为
viewPager.setPageTransformer(false, new ZoomFadeTransformer(viewPager.getPaddingLeft(), MIN_SCALE, MIN_ALPHA));
我正在实现一个 ViewPager,它显示下一个和上一个项目,还使用 ViewPager.PageTransformer 动画页面转换。它具有缩小和淡出效果。为了显示下一个和上一个,我使用负 PageMargin,viewpager 上的填充和 clipToPadding 为 false。这是它的样子
这就是我想要的。问题在于 PageTransform 使用左边缘作为参考,即当图像接触左边缘而不是位于中心时它显示最大缩放。为了解决这个问题,我在代码中使用了一个偏移量,如下所示
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);
}
}
});
我记录了图像居中时的位置值并找到了偏移量。但此偏移量仅适用于 xxhdpi 设备。在 xxxhdpi 上,值为 0.12068965f。此外,当我更改 ViewPager 上的填充时,偏移量也会发生变化。此外,下一个和上一个的预览大小随 dpi 变化。
问题
如何计算填充、边距,尤其是偏移量以在不同 dpis 之间保持一致的行为?
代码
这是我添加 viewpager 及其填充的布局
<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>
这里是viewpager的初始化代码:
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);
这就是我最终得到的结果:
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);
}
}
}
我把它设为
viewPager.setPageTransformer(false, new ZoomFadeTransformer(viewPager.getPaddingLeft(), MIN_SCALE, MIN_ALPHA));