Android ViewFlipper

分享到:

ViewFlipper可以切换任意控件,之前讲过的ImageSwitcherTextSwitcher只能切换图片和文字,而ViewFlipper直接继承ViewAnimatorViewSwitcher在同一级别。类继承结构如下图:

ViewFlipper

下面通过一个实例了解ViewFlipper具体用法,这个例子综合性比较强很有代表性。用到了手势滑动以及动画效果,最后实现了通过手势的左右滑动来切换图片,整个例子的关键在于如何判断出手势的滑动方向,然后在对应的手势事件内调用showNext()和showPrevious()来显示下一个View或上一个View。 图片切换过程中伴随渐进渐出的动画效果。

主界面XML布局代码:

<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" >
<ViewFlipper
android:id="@+id/viewFlipper"
android:layout_width="match_parent"
android:layout_height="240dp" />
</RelativeLayout>

Activity代码:

package com.my.androidtest;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.Window;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.ViewFlipper;

public class ViewFliperActivity extends Activity implements OnGestureListener {
          
          private static final String TAG = "MainActivity";
  
          private ViewFlipper viewFlipper;
          private GestureDetector detector; //手势检测
          Animation leftInAnimation;
          Animation leftOutAnimation;
          Animation rightInAnimation;
          Animation rightOutAnimation;
  
          @Override
          public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          requestWindowFeature(Window.FEATURE_NO_TITLE);
          setContentView(R.layout.activity_view_fliper);
  
          viewFlipper = (ViewFlipper)findViewById(R.id.viewFlipper);
          detector = new GestureDetector(this);
  
          //往viewFlipper添加View
          viewFlipper.addView(getImageView(R.drawable.img1));
          viewFlipper.addView(getImageView(R.drawable.img2));
          viewFlipper.addView(getImageView(R.drawable.img3));
          viewFlipper.addView(getImageView(R.drawable.img4));
  
          //动画效果
          leftInAnimation = AnimationUtils.loadAnimation(this, R.animator.left_in);
          leftOutAnimation = AnimationUtils.loadAnimation(this, R.animator.left_out);
          rightInAnimation = AnimationUtils.loadAnimation(this, R.animator.right_in);
          rightOutAnimation = AnimationUtils.loadAnimation(this, R.animator.right_out);
          }
         private ImageView getImageView(int id){
          ImageView imageView = new ImageView(this);
          imageView.setImageResource(id);
          return imageView;
          }
         @Override
          public boolean onTouchEvent(MotionEvent event) {
          //touch事件利用手势处理
          return this.detector.onTouchEvent(event); 
          }
         @Override
          public boolean onDown(MotionEvent e) {
          // TODO Auto-generated method stub
          return false;
          }
         @Override
          public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
          float velocityY) {
          //在Log上输出了手势滑动位移坐标,便于调试,可以注示掉这行代码
          Log.i(TAG, "e1="+e1.getX()+" e2="+e2.getX()+" e1-e2="+(e1.getX()-e2.getX()));
  
          if(e1.getX()-e2.getX()>120){
          viewFlipper.setInAnimation(leftInAnimation);
          viewFlipper.setOutAnimation(leftOutAnimation);
          viewFlipper.showNext();//向右滑动调用下一个View
          return true;
          }else if(e1.getX()-e2.getY()<-120){
          viewFlipper.setInAnimation(rightInAnimation);
          viewFlipper.setOutAnimation(rightOutAnimation);
          viewFlipper.showPrevious();//向左滑动调用上一个View
          return true;
          }
          return false;
          }
         @Override
          public void onLongPress(MotionEvent e) {
          // TODO Auto-generated method stub
  
          }
         @Override
          public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
          float distanceY) {
          // TODO Auto-generated method stub
          return false;
          }
         @Override
          public void onShowPress(MotionEvent e) {
          // TODO Auto-generated method stub
  
          }
         @Override
          public boolean onSingleTapUp(MotionEvent e) {
          // TODO Auto-generated method stub
          return false;
          }
  
}

动画效果XML配置文件共有4个,分别对应:左进,左出,右进,右出
left_int.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="100%p"
android:toXDelta="0"
android:duration="600"/>
<alpha
android:fromAlpha="0.1"
android:toAlpha="1.0"
android:duration="600"/>
</set>

left_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="0"
android:toXDelta="-100%p"
android:duration="600"/>
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.1"
android:duration="600"/>
</set>

right_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="-100%p"
android:toXDelta="0"
android:duration="600"/>
<alpha
android:fromAlpha="0.1"
android:toAlpha="1.0"
android:duration="600"/>
</set>

right_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="0"
android:toXDelta="100%p"
android:duration="600"/>
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.1"
android:duration="600"/>
</set>

关于以上XML动画效果文件有几个属性给大家介绍一下:
android:duration 这是动画持续的时间,以毫秒为单位
android:fromAlpha 动画开始时的透明度(0-1)
android:toAlpha 动画结束时的透明度(0-1)
以上4个动画效果XML文件放在项目的/res/animator目录下,如下图所示:

ViewFlipper主要方法:

setInAnimation()
设置View进入屏幕时候使用的动画,该函数有两个版本,一个接受单个参数,类型为android.view.animation.Animation;一个接受两个参数,类型为Context和int,分别为Context对象和定义Animation的resourceID
setOutAnimation()
设置View退出屏幕时候使用的动画,参数setInAnimation方法一样
showPrevious()
显示下一个View,通常配合手势操作
showNext()
显示上一个View,通常配合手势操作
昵    称:
验证码:

相关文档:

Android控件
Android基础知识
Android组件
Android实例