Android手势识别ViewFlipper触摸动画
创始人
2024-07-16 22:40:58
0

我们曾介绍过“在Android开发中使用Gallery实现'多级联动'”和“在Android中实现service动态更新UI界面”。今天给大家介绍一下如何实现Android主页面的左右拖动效果。实现起来很简单,就是使用ViewFlipper来将您要来回拖动的View装在一起,然后与GestureDetector手势识别类来联动,确定要显示哪个View,加上一点点动画效果即可。比如当手指向左快速滑动时跳转到上一个View,手指向右快速滑动时跳转到下一个View,本例中使用图片作为各个View的页面,实现左右快速滑动显示不同的图片。

Android View
Android View

首先来看看我们的layout,如下所示:

  1.  
  2.      
  3.          
  4.          
  5.          
  6.          
  7.      
  8.  
  9.  

如上所示,在ViewFlipper中放置多个layout(接下来会在不同的layout中来回滑动),ViewFlipper在同一个页面就显示其中一个layout。

ViewFlipper中的四个layout很简单,我们就放置一张图片,如下所示:

  1.  
  2.    
  3.  
  4.  

接下来我们来看看Activity,我们的Activity需要实现两个接口OnGestureListener,OnTouchListener。具体的代码如下所示,代码中都有相应的注释,这里就不再详述。

  1. package com.ideasandroid.demo;  
  2. import android.app.Activity;  
  3. import android.os.Bundle;  
  4. import android.view.GestureDetector;  
  5. import android.view.MotionEvent;  
  6. import android.view.View;  
  7. import android.view.GestureDetector.OnGestureListener;  
  8. import android.view.View.OnTouchListener;  
  9. import android.view.animation.AccelerateInterpolator;  
  10. import android.view.animation.Animation;  
  11. import android.view.animation.TranslateAnimation;  
  12. import android.widget.ViewFlipper;  
  13. public class ViewFlipperDemo extends Activity implementsOnGestureListener,OnTouchListener{  
  14.     private ViewFlipper mFlipper;  
  15.     GestureDetector mGestureDetector;  
  16.     private int mCurrentLayoutState;  
  17.     private static final int FLING_MIN_DISTANCE = 100;  
  18.     private static final int FLING_MIN_VELOCITY = 200;  
  19.    
  20.     @Override  
  21.     public void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         setContentView(R.layout.main);  
  24.         mFlipper = (ViewFlipper) findViewById(R.id.flipper);  
  25.         //注册一个用于手势识别的类  
  26.         mGestureDetector = new GestureDetector(this);  
  27.         //给mFlipper设置一个listener  
  28.         mFlipper.setOnTouchListener(this);  
  29.         mCurrentLayoutState = 0;  
  30.         //允许长按住ViewFlipper,这样才能识别拖动等手势  
  31.         mFlipper.setLongClickable(true);  
  32.     }  
  33.    
  34.     /**  
  35.      * 此方法在本例中未用到,可以指定跳转到某个页面  
  36.      * @param switchTo  
  37.      */  
  38.     public void switchLayoutStateTo(int switchTo) {  
  39.         while (mCurrentLayoutState != switchTo) {  
  40.             if (mCurrentLayoutState > switchTo) {  
  41.                 mCurrentLayoutState--;  
  42.                 mFlipper.setInAnimation(inFromLeftAnimation());  
  43.                 mFlipper.setOutAnimation(outToRightAnimation());  
  44.                 mFlipper.showPrevious();  
  45.             } else {  
  46.                 mCurrentLayoutState++;  
  47.                 mFlipper.setInAnimation(inFromRightAnimation());  
  48.                 mFlipper.setOutAnimation(outToLeftAnimation());  
  49.                 mFlipper.showNext();  
  50.             }  
  51.    
  52.         }  
  53.         ;  
  54.     }  
  55.    
  56.     /**  
  57.      * 定义从右侧进入的动画效果  
  58.      * @return  
  59.      */  
  60.     protected Animation inFromRightAnimation() {  
  61.         Animation inFromRight = new TranslateAnimation(  
  62.                 Animation.RELATIVE_TO_PARENT, +1.0f,  
  63.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  64.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  65.                 Animation.RELATIVE_TO_PARENT, 0.0f);  
  66.         inFromRight.setDuration(500);  
  67.         inFromRight.setInterpolator(new AccelerateInterpolator());  
  68.         return inFromRight;  
  69.     }  
  70.    
  71.     /**  
  72.      * 定义从左侧退出的动画效果  
  73.      * @return  
  74.      */  
  75.     protected Animation outToLeftAnimation() {  
  76.         Animation outtoLeft = new TranslateAnimation(  
  77.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  78.                 Animation.RELATIVE_TO_PARENT, -1.0f,  
  79.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  80.                 Animation.RELATIVE_TO_PARENT, 0.0f);  
  81.         outtoLeft.setDuration(500);  
  82.         outtoLeft.setInterpolator(new AccelerateInterpolator());  
  83.         return outtoLeft;  
  84.     }  
  85.    
  86.     /**  
  87.      * 定义从左侧进入的动画效果  
  88.      * @return  
  89.      */  
  90.     protected Animation inFromLeftAnimation() {  
  91.         Animation inFromLeft = new TranslateAnimation(  
  92.                 Animation.RELATIVE_TO_PARENT, -1.0f,  
  93.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  94.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  95.                 Animation.RELATIVE_TO_PARENT, 0.0f);  
  96.         inFromLeft.setDuration(500);  
  97.         inFromLeft.setInterpolator(new AccelerateInterpolator());  
  98.         return inFromLeft;  
  99.     }  
  100.    
  101.     /**  
  102.      * 定义从右侧退出时的动画效果  
  103.      * @return  
  104.      */  
  105.     protected Animation outToRightAnimation() {  
  106.         Animation outtoRight = new TranslateAnimation(  
  107.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  108.                 Animation.RELATIVE_TO_PARENT, +1.0f,  
  109.                 Animation.RELATIVE_TO_PARENT, 0.0f,  
  110.                 Animation.RELATIVE_TO_PARENT, 0.0f);  
  111.         outtoRight.setDuration(500);  
  112.         outtoRight.setInterpolator(new AccelerateInterpolator());  
  113.         return outtoRight;  
  114.     }  
  115.    
  116.     public boolean onDown(MotionEvent e) {  
  117.         // TODO Auto-generated method stub  
  118.         return false;  
  119.     }  
  120.    
  121.     /*  
  122.      * 用户按下触摸屏、快速移动后松开即触发这个事件  
  123.      * e1:第1个ACTION_DOWN MotionEvent  
  124.      * e2:***一个ACTION_MOVE MotionEvent  
  125.      * velocityX:X轴上的移动速度,像素/秒  
  126.      * velocityY:Y轴上的移动速度,像素/秒  
  127.      * 触发条件 :  
  128.      * X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒  
  129.      */  
  130.     public boolean onFling(MotionEvent e1, MotionEvent e2, floatvelocityX,  
  131.             float velocityY) {  
  132.         if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE  
  133.                 && Math.abs(velocityX) > FLING_MIN_VELOCITY) {  
  134.             // 当像左侧滑动的时候  
  135.             //设置View进入屏幕时候使用的动画  
  136.             mFlipper.setInAnimation(inFromRightAnimation());  
  137.             //设置View退出屏幕时候使用的动画  
  138.             mFlipper.setOutAnimation(outToLeftAnimation());  
  139.             mFlipper.showNext();  
  140.         } else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE  
  141.                 && Math.abs(velocityX) > FLING_MIN_VELOCITY) {  
  142.             // 当像右侧滑动的时候  
  143.             mFlipper.setInAnimation(inFromLeftAnimation());  
  144.             mFlipper.setOutAnimation(outToRightAnimation());  
  145.             mFlipper.showPrevious();  
  146.         }  
  147.         return false;  
  148.     }  
  149.    
  150.     public void onLongPress(MotionEvent e) {  
  151.         // TODO Auto-generated method stub  
  152.    
  153.     }  
  154.    
  155.     public boolean onScroll(MotionEvent e1, MotionEvent e2, floatdistanceX,  
  156.             float distanceY) {  
  157.         return false;  
  158.     }  
  159.    
  160.     public void onShowPress(MotionEvent e) {  
  161.         // TODO Auto-generated method stub  
  162.    
  163.     }  
  164.    
  165.     public boolean onSingleTapUp(MotionEvent e) {  
  166.         // TODO Auto-generated method stub  
  167.         return false;  
  168.     }  
  169.     public boolean onTouch(View v, MotionEvent event) {  
  170.         // 一定要将触屏事件交给手势识别类去处理(自己处理会很麻烦的)  
  171.         return mGestureDetector.onTouchEvent(event);  
  172.     }  
  173. }  
  174.  

希望本文对您有所帮助!

【编辑推荐】

  1. 在Android开发中使用Gallery实现“多级联动”
  2. 在Android中实现service动态更新UI界面
  3. Android数据库事务浅析
  4. Android的UI设计与后台线程交互
  5. Android触屏textview及listview对比验证

相关内容

热门资讯

如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...
20个非常棒的扁平设计免费资源 Apple设备的平面图标PSD免费平板UI 平板UI套件24平图标Freen平板UI套件PSD径向平...
德国电信门户网站可实时显示全球... 德国电信周三推出一个门户网站,直观地实时提供其安装在全球各地的传感器网络检测到的网络攻击状况。该网站...
着眼MAC地址,解救无法享受D... 在安装了DHCP服务器的局域网环境中,每一台工作站在上网之前,都要先从DHCP服务器那里享受到地址动...
为啥国人偏爱 Mybatis,... 关于 SQL 和 ORM 的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行...