屏幕切换指的是在同一个Activity内屏幕间的切换,ViewFlipper继承了Framelayout类,ViewAnimator类的作用是为FrameLayout里面的View切换提供动画效果。如下动图:
该类有如下几个和动画相关的函数:
setInAnimation:设置View进入屏幕时候使用的动画,该函数有两个版本,一个接受单个参数,类型为android.view.animation.Animation;一个接受两个参数,类型为Context和int,分别为Context对象和定义Animation的resourceID。
setOutAnimation: 设置View退出屏幕时候使用的动画,参数setInAnimation函数一样。
showNext: 调用该函数来显示FrameLayout里面的下一个View。
showPrevious: 调用该函数来显示FrameLayout里面的上一个View。
下面通过坐标轴的形式为大家演示动画实现方式:
由上图可知,以屏幕左下角为数学坐标轴的原点,屏幕下边框为X轴,左边框为Y轴,当前屏幕显示为图二,如果要看图一,则需要图一由左至右(相对屏幕而言)进入屏幕,图一X轴初始坐标为-100%p,移动到屏幕位置时图一X轴变为0(因为本次演示为横向滑动,所以不涉及Y轴);同理图三要进入屏幕,则需由右至左,X轴由100%p变为0.清楚了坐标位置,我们要实现四种动画效果,就会很简单,下面代码(需建立在res目录下自建的anim文件夹下)演示四种动画效果:
in_leftright.xml——从左到右进入屏幕:
1 <?xml version="1.0" encoding="utf-8"?> 2 <set xmlns:android="http://schemas.android.com/apk/res/android"> 3 <translate 4 android:duration="500" 5 android:fromXDelta="-100%p" 6 android:toXDelta="0"/> 7 </set>
out_leftright.xml——从左到右出去屏幕:
1 <?xml version="1.0" encoding="utf-8"?> 2 <set xmlns:android="http://schemas.android.com/apk/res/android"> 3 <translate 4 android:duration="500" 5 android:fromXDelta="0" 6 android:toXDelta="100%p"/> 7 </set>
in_rightleft.xml——从右到左进入屏幕:
1 <?xml version="1.0" encoding="utf-8"?> 2 <set xmlns:android="http://schemas.android.com/apk/res/android"> 3 <translate 4 android:duration="500" 5 android:fromXDelta="100%p" 6 android:toXDelta="0"/> 7 8 </set>
out_rightleft.xml——从右到左出去屏幕:
1 <?xml version="1.0" encoding="utf-8"?> 2 <set xmlns:android="http://schemas.android.com/apk/res/android"> 3 <translate 4 android:duration="500" 5 android:fromXDelta="0" 6 android:toXDelta="-100%p"/> 7 </set>
动画效果建立完成,建立
Layout中view_layout.xml布局文件(本次直接将定义动画的三张图片直接通过LinearLayOut布局到ViewFlipper中):
1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" android:layout_width="match_parent" 4 android:layout_height="match_parent"> 5 <ViewFlipper 6 android:id="@+id/vf" 7 android:layout_width="match_parent" 8 android:layout_height="match_parent"> 9 <LinearLayout 10 android:layout_width="match_parent" 11 android:layout_height="match_parent"> 12 <ImageView 13 android:layout_width="match_parent" 14 android:layout_height="match_parent" 15 android:src="@mipmap/sample_1" /> 16 </LinearLayout> 17 <LinearLayout 18 android:layout_width="match_parent" 19 android:layout_height="match_parent"> 20 <ImageView 21 android:layout_width="match_parent" 22 android:layout_height="match_parent" 23 android:src="@mipmap/sample_2" /> 24 </LinearLayout> 25 <LinearLayout 26 android:layout_width="match_parent" 27 android:layout_height="match_parent"> 28 <ImageView 29 android:layout_width="match_parent" 30 android:layout_height="match_parent" 31 android:src="@mipmap/sample_3" /> 32 </LinearLayout> 33 </ViewFlipper> 34 </LinearLayout>
Activity中Java功能实现代码:
1 import android.os.Bundle; 2 import android.support.annotation.Nullable; 3 import android.support.v7.app.AppCompatActivity; 4 import android.view.MotionEvent; 5 import android.view.View; 6 import android.widget.ViewFlipper; 7 /** 8 * Created by panchengjia on 2016/11/28. 9 */ 10 public class FlipperActivity extends AppCompatActivity implements View.OnTouchListener{ 11 private ViewFlipper vf; 12 float startX;//声明手指按下时X的坐标 13 float endX;//声明手指松开后X的坐标 14 @Override 15 protected void onCreate(@Nullable Bundle savedInstanceState) { 16 super.onCreate(savedInstanceState); 17 setContentView(R.layout.viewflipper_layout); 18 vf= (ViewFlipper) findViewById(R.id.vf); 19 vf.setOnTouchListener(this); 20 } 21 @Override 22 public boolean onTouch(View v, MotionEvent event) { 23 //判断捕捉到的动作为按下,则设置按下点的X坐标starX 24 if(event.getAction()==MotionEvent.ACTION_DOWN){ 25 startX=event.getX(); 26 //判断捕捉到的动作为抬起,则设置松开点X坐标endX 27 }else if(event.getAction()==MotionEvent.ACTION_UP){ 28 endX=event.getX(); 29 //由右到左滑动屏幕,X值会减小,图片由屏幕右侧进入屏幕 30 if(startX>endX){ 31 //进出动画成对 32 vf.setInAnimation(this,R.anim.in_rightleft); 33 vf.setOutAnimation(this,R.anim.out_rightleft); 34 vf.showNext();//显示下个view 35 //由左到右滑动屏幕,X值会增大,图片由屏幕左侧进入屏幕 36 }else if(startX<endX){ 37 vf.setInAnimation(this,R.anim.in_leftright); 38 vf.setOutAnimation(this,R.anim.out_leftright); 39 vf.showPrevious();//显示上个view 40 } 41 } 42 return true; 43 } 44 }
在练习这里时,动画的显示效果方式困扰了我好久,这才想到了通过坐标轴的形式体现动画实现原理,画成的那一瞬间,整个人顿似醍醐灌顶,忍不住想要写成博文分享给大家,共勉!
后续更改补充:发文后,好友提醒在安卓开发中Android屏幕坐标系统,不同于一般数学模型,原点应该位于左上角且Y轴向下递增,经过查阅资料,确实如此,现更改坐标轴如下:
同时希望更为朋友如果发现博文里有不符合技术原理的地方,及时提出,我会做更改,以免误扰大家,本次谢谢骁敏。