您的位置:首页 > 其它

Viewpager翻页3D动效

2016-11-16 21:51 162 查看
现在越来越多的app中为了用户体验的提升和视觉效果的增强,在界面翻页时,通常会增加一些3D动效,会大大提高界面的视觉冲击,如下图所示:

旋转式:



平面缩放式:



那么针对这两种效果,我们通过代码实现说明:

自定义viewpager:

public class MeasureZoomViewPager extends ViewPager {
private int viewPagerWidth;
private int viewPagerHeight;

public MeasureZoomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);

this.setPageMargin(-30);
this.setOffscreenPageLimit(3);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MeasureZoomViewPager);
int typedArrayInt = typedArray.getInt(R.styleable.MeasureZoomViewPager_viewPagerStyle, 0);
switch (typedArrayInt) {
case 1:
// 以下是设置滑动时和展示的当前页面有缩小和模糊的效果
this.setPageTransformer(true, new ZoomOutPageTransformer());
break;
case 2:
this.setPageTransformer(true, new RotateTransformation());
break;
}
int width = context.getResources().getDisplayMetrics().widthPixels;
// 表示设置图片占屏幕宽的4/5
viewPagerWidth = width * 3 / 5;
// 表示设置图片占原图高的1.2倍
viewPagerHeight = width * 6 / 5;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
super.onMeasure(MeasureSpec.makeMeasureSpec(viewPagerWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(viewPagerHeight, MeasureSpec.EXACTLY));
}
}


其实我们主要修改的是每个交换展示的子页的展示效果,也就是viewpager中PageTransformer属性,首先我们先完成旋转式RotateTransformation:

public class RotateTransformation implements ViewPager.PageTransformer {

private static final float MIN_SCALE = 0.85f;
private static final float MIN_ALPHA = 0.5f;
private static final float MAX_ROTATE = 30;
private Camera camera = new Camera();

@Override
public void transformPage(View page, float position) {
float centerX = page.getWidth() / 2;
float centerY = page.getHeight() / 2;
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float rotate = 20 * Math.abs(position);
if (position < -1) {

} else if (position < 0) {
page.setScaleX(scaleFactor);
page.setScaleY(scaleFactor);
page.setRotationY(rotate);
} else if (position >= 0 && position < 1) {
page.setScaleX(scaleFactor);
page.setScaleY(scaleFactor);
page.setRotationY(-rotate);
} else if (position >= 1) {
page.setScaleX(scaleFactor);
page.setScaleY(scaleFactor);
page.setRotationY(-rotate);
}
}
}


平面缩放式ZoomOutPageTransformer:

public class ZoomOutPageTransformer implements ViewPager.PageTransformer {

private static final float MIN_SCALE = 0.85f;// 最小缩小倍数
private static final float MIN_ALPHA = 0.4f;// 最小透明度
private Runnable runnable;

/**
* position越接近于0,表示越靠近于中间
*
* @param view
* @param position
*/
@SuppressLint("NewApi")
@Override
public void transformPage(final View view, final float position) {

runnable = new Runnable() {
public void run() {

float absPosition = Math.abs(position);
if (absPosition > 1.0001) {
// 在边缘显示时显示最小缩小倍数和最小透明度
} else if (absPosition >= 1) {
view.setScaleX(MIN_SCALE);
view.setScaleY(MIN_SCALE);
view.setAlpha(MIN_ALPHA);
} else {
// 在边缘显示时显示最小缩小倍数和最小透明度
float scaleFactor = 1f - (1 - MIN_SCALE) * absPosition;
float alpheFactor = 1f - (1 - MIN_ALPHA) * absPosition;
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
view.setAlpha(alpheFactor);
}
runnable = null;
}
};
view.post(runnable);
}
}


attrs.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MeasureZoomViewPager">
<attr name="viewPagerStyle" format="integer">
<enum name="none" value="0"></enum>
<enum name="zoom" value="1"></enum>
<enum name="rotate" value="2"></enum>
</attr>
</declare-styleable>
</resources>


主界面:

public class MyActivity extends Activity{
private MeasureZoomViewPager viewPager;
@Override
public View onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);

viewPager = (MeasureZoomViewPager)view.findViewById(R.id.viewPager);

List<View> list = new ArrayList<>();
View view1 =LayoutInflater.from(context).inflate(R.layout.layout1, null);
View view2 = LayoutInflater.from(context).inflate(R.layout.layout2, null);
list.add(view1);
list.add(view2);
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(list);
viewPager.setAdapter(viewPagerAdapter);
}

public class ViewPagerAdapter extends PagerAdapter {

private List<View> list;

public ViewPagerAdapter(List<View> list) {
super();
this.list = list;
}

@Override
public int getCount() {
return list.size();
}

@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}

@Override
public void destroyItem(View container, int position, Object object) {
((ViewPager) container).removeView(list.get(position));
}

@Override
public Object instantiateItem(View container, int position) {
View view = list.get(position);
ViewPager viewPager = (ViewPager) container;
viewPager.removeView(view);
viewPager.addView(view);
return view;
}
}


主界面布局:

//MeasureZoomViewPager在使用时注意布局
//(layerType表示界面可以有多个子页;
//clipChildren表示子页超出的部分也显示;
//viewPagerStyle表示viewpager滑动的模式,其中zoom为缩放式的,两侧子页和中间子页平行;rotate为旋转模式,两侧子页围绕中间子页倾斜显示;none不加任何模式):

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:layerType="software">

<MeasureZoomViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:viewPagerStyle="zoom"
android:clipChildren="false" />
</RelativeLayout>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  viewpager