概述
ViewFlipper用于一个Activity中多个View的切换,配上手势操作,给人的用户体验会更好。本文参考API DEMO中的Animation实例,对ViewFlipper的用法、Animation中切屏效果做了简单的总结。应用场景为手势切屏对多图片的浏览。最后,ViewFlipper在手指滑动指定距离后,立即实现切换,并没有达到跟随手指移动的应用效果。
viewFlipper布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ViewFlipper
android:id="@+id/ViewFlipper"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ViewFlipper>
</LinearLayout>
初始化viewFlipper
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.viewflipper);
// 注册一个GestureDetector
detector = new GestureDetector(this);
flipper = (ViewFlipper) findViewById(R.id.ViewFlipper);
ImageView image1 = new ImageView(this);
image1.setBackgroundResource(R.drawable.image1);
// 增加第一个view
flipper.addView(image1);
ImageView image2 = new ImageView(this);
image2.setBackgroundResource(R.drawable.image2);
// 增加第二个view
flipper.addView(image2);
ImageView image3 = new ImageView(this);
image3.setBackgroundResource(R.drawable.image3);
//增加第三个view
flipper.addView(image3);
}
监听OnGestureListener
在创建主Activity的时候,需要实现OnGestureListener接口,并且重写onFling()方法:
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
Log.d(TAG, "e1.X->"+e1.getX()+" e2.X->"+e2.getX()+"\n");
if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE) {//fling distance
//设置View进入和退出的动画效果
this.flipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_in));
this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_left_out));
this.flipper.showNext();
return true;
}
if (e1.getX() - e2.getX() < -FLING_MIN_DISTANCE) {
this.flipper.setInAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_in));
this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this,
R.anim.push_right_out));
this.flipper.showPrevious();
return true;
}
return false;
}
需要注意的是,必须对onTouchEvent()重写,将触摸事件交给手势处理,代码片段如下:
@Override
public boolean onTouchEvent(MotionEvent event) {
return this.detector.onTouchEvent(event);
}
关于切屏动画
切屏动画引入方法:
flipper.setInAnimation(AnimationUtils.loadAnimation(mContext,
R.anim.push_left_in));
flipper.setOutAnimation(AnimationUtils.loadAnimation(mContext,
R.anim.push_left_out));
动画文件在工程中的路径结构:
Android_project->res->anim
常用的动画文件:l Push_left_in
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="300"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" />
</set>
l Push_left_out
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="-100%p" android:duration="300"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="300" />
</set>
l Push_right_in
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-100%p" android:toXDelta="0" android:duration="300"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" />
</set>
l Push_right_out
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="100%p" android:duration="300"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="300" />
</set>
l Push_up_in
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="100%p" android:toYDelta="0" android:duration="300"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="300" />
</set>
l Push_up_out
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="0" android:toYDelta="-100%p" android:duration="300"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="300" />
</set>