左右页面滑动

前言

通过左右滑动屏幕来切换页面,有4种方式:

(0) 使用ScrollLayout;

(1) 使用动画;

(2) Activity 实现 OnTouchListener 和 OnGestureListener 接口;

(3) 使用 ViewPager;

本文将对上述各个方式逐一介绍。

(0)使用ScrollLayout

将scrolllayout 的布局方向设置为水平,当layout的水平尺寸大于手机屏幕时,即可实现左右滑动效果。有1款叫做 do it tomorrow 的应用,就是典型的代表。解压后可以看到,其背景图片其实是1张1280x960的图片(如下图),隐藏滚动条,即有水平滑动的效果。

(1)使用动画

这里的动画是指,使用Activity 中的 overridePendingTransition(,) 方法,具体能实现的动画效果如下表:

 

动画效果列表
淡入淡出效果 overridePendingTransition(R.anim.fade, R.anim.hold);
放大淡出效果 overridePendingTransition(R.anim.my_scale_action,R.anim.my_alpha_action);
转动淡出效果 overridePendingTransition(R.anim.scale_rotate,R.anim.my_alpha_action);
转动淡出效果 overridePendingTransition(R.anim.scale_translate_rotate,R.anim.my_alpha_action);
左上角展开淡出效果 overridePendingTransition(R.anim.scale_translate,R.anim.my_alpha_action);
压缩变小淡出效果 overridePendingTransition(R.anim.hyperspace_in,R.anim.hyperspace_out);
右往左推出效果 overridePendingTransition(R.anim.push_left_in,R.anim.push_left_out);
下往上推出效果 overridePendingTransition(R.anim.push_up_in,R.anim.push_up_out);
左右交错效果 overridePendingTransition(R.anim.slide_left,R.anim.slide_right);
放大淡出效果 overridePendingTransition(R.anim.wave_scale,R.anim.my_alpha_action);
缩小效果 overridePendingTransition(R.anim.zoom_enter,R.anim.zoom_exit);
上下交错效果 overridePendingTransition(R.anim.slide_up_in,R.anim.slide_down_out);

 

我们以“右往左推出效果”为例,其中R.anim.slide_left 和 R.anim.slide_right 文件分别如下:

 

[html] view plain copy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android" >  
  3.     <translate android:fromXDelta="0%p" android:toXDelta="-100%p"  
  4.         android:duration="500" />  
  5. </set>  

 

 

[html] view plain copy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <set xmlns:android="http://schemas.android.com/apk/res/android" >  
  3.     <translate android:fromXDelta="100%p" android:toXDelta="0%p"  
  4.         android:duration="500" />  
  5. </set>  

上述xml文件中,有3个值需要解释:fromXDelta 是指页面滑动的起点,toXDelta 是指页面滑动的终点,duration 是指滑动耗时,单位为毫秒(1/1000 秒)。可以实现AnimLeftActivity  和 AnimRightActivity 之间的左右滑动。具体手机屏幕和 x 轴、y 轴的关系见下图:

 


public class AnimLeftActivity extends Activity {

[java] view plain copy
 
  1.  private Button btnStart = null;  
  2.   
  3.  @Override  
  4.  public void onCreate(Bundle savedInstanceState) {  
  5.      super.onCreate(savedInstanceState);  
  6.        
  7.      // 移除Title  
  8.      requestWindowFeature(Window.FEATURE_NO_TITLE);  
  9.        
  10.      setContentView(R.layout.left_layout);  
  11.   
  12.      // 开始按钮  
  13.      btnStart = (Button) findViewById(R.id.btn_anim_left);  
  14.        
  15.      /** 
  16.       * 开始测试按钮 的监听函数 
  17.       *  
  18.       * */  
  19.      btnStart.setOnClickListener(new View.OnClickListener() {  
  20.   
  21. public void onClick(View view) {  
  22.       
  23.     Intent i = new Intent(getApplicationContext(), AnimRightActivity.class);  
  24.     startActivity(i);  
  25.       
  26.     // 设置切换动画,从右边进入,左边退出  
  27.        overridePendingTransition(R.anim.right_activity_enter_from_right, R.anim.left_activity_out_to_left);  
  28.          
  29.     finish();             
  30. }  
  31. );  
  32.  }  
[java] view plain copy
 
  1. public class AnimRightActivity extends Activity {  
  2.       
  3.     private Button btnStart = null;  
  4.       
  5.     public void onCreate(Bundle savedInstanceState) {  
  6.           
  7.         super.onCreate(savedInstanceState);  
  8.           
  9.         // 移除Title  
  10.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  11.           
  12.         setContentView(R.layout.right_layout);  
  13.           
  14.         // 开始按钮  
  15.         btnStart = (Button) findViewById(R.id.btn_anim_right);  
  16.           
  17.         /** 
  18.          * 开始测试按钮 的监听函数 
  19.          *  
  20.          * */  
  21.         btnStart.setOnClickListener(new View.OnClickListener() {  
  22.               
  23.             public void onClick(View view) {  
  24.                 Intent i = new Intent(getApplicationContext(), AnimLeftActivity.class);  
  25.                 startActivity(i);  
  26.                   
  27.                 // 设置切换动画,从右边进入,左边退出  
  28.                 overridePendingTransition(R.anim.left_activity_enter_from_left, R.anim.right_activity_out_to_left);  
  29.                   
  30.                 finish();           }  
  31.         });  
  32.     }  
  33. }  

 

(2)Activity 实现 OnTouchListener 和 OnGestureListener 接口

[java] view plain copy
 
  1. public class GestureLeftActivity extends Activity implements OnTouchListener, OnGestureListener {  
  2.       
  3.     // 按钮  
  4.     private Button btnStart = null;  
  5.       
  6.     // 监听左划动作  
  7.     private RelativeLayout rlLeft = null;  
  8.     private GestureDetector gd    = null;  
  9.       
  10.     // 最小的水平有效划动距离和速度,超过该距离和速度才触发划动事件  
  11.     private int slideMinDistance = 20;    
  12.     private int slideMinVelocity = 0;    
  13.       
  14.     @Override  
  15.     public void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.           
  18.         // 移除Title  
  19.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  20.           
  21.         setContentView(R.layout.left_layout);  
  22.           
  23.         btnStart = (Button) findViewById(R.id.btn_anim_left);  
  24.         btnStart.setText("");  
  25.           
  26.         btnStart.setOnClickListener(new View.OnClickListener() {  
  27.               
  28.             public void onClick(View v) {  
  29.                 Toast.makeText(GestureLeftActivity.this, "请向左滑动", Toast.LENGTH_SHORT).show();  
  30.             }  
  31.         });  
  32.           
  33.         // 处理左划事件  
  34.         gd = new GestureDetector((OnGestureListener) this);      
  35.         rlLeft = (RelativeLayout) findViewById(R.id.rl_left);      
  36.         rlLeft.setOnTouchListener(this);      
  37.         rlLeft.setLongClickable(true);  
  38.     }  
  39.       
  40.       
  41.     /** 
  42.      * 滑动到手写页面 
  43.       * @Title:       slideToAnalyser 
  44.       * @Description: TODO 
  45.       * @param         
  46.       * @return       void 
  47.       * @throws 
  48.      */  
  49.     private void slideToGestureRightActivity() {  
  50.         Intent i = new Intent(getApplicationContext(), GestureRightActivity.class);  
  51.         startActivity(i);  
  52.           
  53.         // 设置切换动画,从右边进入,左边退出  
  54.         overridePendingTransition(R.anim.right_activity_enter_from_right, R.anim.left_activity_out_to_left);  
  55.           
  56.         finish();  
  57.     }  
  58.       
  59.     /* 
  60.       * <p>Title: onDown</p> 
  61.       * <p>Description: </p> 
  62.       * @param arg0 
  63.       * @return 
  64.       * @see android.view.GestureDetector.OnGestureListener#onDown(android.view.MotionEvent) 
  65.       */  
  66.     public boolean onDown(MotionEvent arg0) {  
  67.   
  68.         // TODO Auto-generated method stub  
  69.         return false;  
  70.     }  
  71.   
  72.   
  73.     /* 
  74.       * <p>Title: onFling</p> 
  75.       * <p>Description: </p> 
  76.       * @param e1 
  77.       * @param e2 
  78.       * @param velocityX 
  79.       * @param velocityY 
  80.       * @return 
  81.       * @see android.view.GestureDetector.OnGestureListener#onFling(android.view.MotionEvent, android.view.MotionEvent, float, float) 
  82.       */  
  83.     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {  
  84.   
  85.         if (((e1.getX() - e2.getX()) > slideMinDistance) && Math.abs(velocityX) > slideMinVelocity) {    
  86.                 
  87.             // 切换Activity    
  88.             slideToGestureRightActivity();  
  89.             Toast.makeText(this, "向左手势", Toast.LENGTH_SHORT).show();    
  90.         } else if (e2.getX() - e1.getX() > slideMinDistance && Math.abs(velocityX) > slideMinVelocity) {    
  91.         
  92.             // 切换Activity    
  93.             // Intent intent = new Intent(ViewSnsActivity.this, UpdateStatusActivity.class);    
  94.             // startActivity(intent);    
  95.             Toast.makeText(this, "向右手势", Toast.LENGTH_SHORT).show();  
  96.         }  
  97.         
  98.         return false;    
  99.     }  
  100.   
  101.   
  102.     /* 
  103.       * <p>Title: onLongPress</p> 
  104.       * <p>Description: </p> 
  105.       * @param e 
  106.       * @see android.view.GestureDetector.OnGestureListener#onLongPress(android.view.MotionEvent) 
  107.       */  
  108.       
  109.       
  110.     public void onLongPress(MotionEvent e) {  
  111.   
  112.         // TODO Auto-generated method stub  
  113.           
  114.     }  
  115.   
  116.   
  117.     /* 
  118.       * <p>Title: onScroll</p> 
  119.       * <p>Description: </p> 
  120.       * @param e1 
  121.       * @param e2 
  122.       * @param distanceX 
  123.       * @param distanceY 
  124.       * @return 
  125.       * @see android.view.GestureDetector.OnGestureListener#onScroll(android.view.MotionEvent, android.view.MotionEvent, float, float) 
  126.       */  
  127.       
  128.       
  129.     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {  
  130.   
  131.         // TODO Auto-generated method stub  
  132.         return false;  
  133.     }  
  134.   
  135.   
  136.     /* 
  137.       * <p>Title: onShowPress</p> 
  138.       * <p>Description: </p> 
  139.       * @param e 
  140.       * @see android.view.GestureDetector.OnGestureListener#onShowPress(android.view.MotionEvent) 
  141.       */  
  142.       
  143.       
  144.     public void onShowPress(MotionEvent e) {  
  145.   
  146.         // TODO Auto-generated method stub  
  147.           
  148.     }  
  149.   
  150.   
  151.     /* 
  152.       * <p>Title: onSingleTapUp</p> 
  153.       * <p>Description: </p> 
  154.       * @param e 
  155.       * @return 
  156.       * @see android.view.GestureDetector.OnGestureListener#onSingleTapUp(android.view.MotionEvent) 
  157.       */  
  158.       
  159.       
  160.     public boolean onSingleTapUp(MotionEvent e) {  
  161.   
  162.         // TODO Auto-generated method stub  
  163.         return false;  
  164.     }  
  165.   
  166.   
  167.     /* 
  168.       * <p>Title: onTouch</p> 
  169.       * <p>Description: </p> 
  170.       * @param v 
  171.       * @param event 
  172.       * @return 
  173.       * @see android.view.View.OnTouchListener#onTouch(android.view.View, android.view.MotionEvent) 
  174.       */  
  175.       
  176.       
  177.     public boolean onTouch(View v, MotionEvent event) {  
  178.   
  179.         // TODO Auto-generated method stub  
  180.         return gd.onTouchEvent(event);  
  181.     }  
  182.       
  183.     public boolean dispatchTouchEvent(MotionEvent ev) {  
  184.   
  185.         gd.onTouchEvent(ev);  
  186.           
  187.         // scroll.onTouchEvent(ev);  
  188.         return super.dispatchTouchEvent(ev);  
  189.     }   
  190. }  


 
[java] view plain copy
 
  1. public class GestureRightActivity extends Activity implements OnTouchListener, OnGestureListener {  
  2.       
  3.     // 按钮  
  4.     private Button btnStart = null;  
  5.       
  6.     // 监听左划动作  
  7.     private RelativeLayout rlRight = null;  
  8.     private GestureDetector gd    = null;  
  9.       
  10.     // 最小的水平有效划动距离和速度,超过该距离和速度才触发划动事件  
  11.     private int slideMinDistance = 20;    
  12.     private int slideMinVelocity = 0;    
  13.       
  14.     @Override  
  15.     public void onCreate(Bundle savedInstanceState) {  
  16.         super.onCreate(savedInstanceState);  
  17.           
  18.         // 移除Title  
  19.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  20.           
  21.         setContentView(R.layout.right_layout);  
  22.           
  23.         btnStart = (Button) findViewById(R.id.btn_anim_right);  
  24.         btnStart.setText("");  
  25.           
  26.         btnStart.setOnClickListener(new View.OnClickListener() {  
  27.               
  28.             public void onClick(View v) {  
  29.                 Toast.makeText(GestureRightActivity.this, "请向右滑动", Toast.LENGTH_SHORT).show();  
  30.             }  
  31.         });  
  32.           
  33.         // 处理左划事件  
  34.         gd = new GestureDetector((OnGestureListener) this);      
  35.         rlRight = (RelativeLayout) findViewById(R.id.rl_right);      
  36.         rlRight.setOnTouchListener(this);      
  37.         rlRight.setLongClickable(true);  
  38.     }  
  39.       
  40.       
  41.     /** 
  42.      * 滑动到手写页面 
  43.       * @Title:       slideToAnalyser 
  44.       * @Description: TODO 
  45.       * @param         
  46.       * @return       void 
  47.       * @throws 
  48.      */  
  49.     private void slideToGestureLeftActivity() {  
  50.         Intent i = new Intent(getApplicationContext(), GestureLeftActivity.class);  
  51.         startActivity(i);  
  52.           
  53.         // 设置切换动画,从右边进入,左边退出  
  54.         overridePendingTransition(R.anim.left_activity_enter_from_left, R.anim.right_activity_out_to_left);  
  55.           
  56.         finish();  
  57.     }  
  58.       
  59.     /* 
  60.       * <p>Title: onDown</p> 
  61.       * <p>Description: </p> 
  62.       * @param arg0 
  63.       * @return 
  64.       * @see android.view.GestureDetector.OnGestureListener#onDown(android.view.MotionEvent) 
  65.       */  
  66.     public boolean onDown(MotionEvent arg0) {  
  67.   
  68.         // TODO Auto-generated method stub  
  69.         return false;  
  70.     }  
  71.   
  72.   
  73.     /* 
  74.       * <p>Title: onFling</p> 
  75.       * <p>Description: </p> 
  76.       * @param e1 
  77.       * @param e2 
  78.       * @param velocityX 
  79.       * @param velocityY 
  80.       * @return 
  81.       * @see android.view.GestureDetector.OnGestureListener#onFling(android.view.MotionEvent, android.view.MotionEvent, float, float) 
  82.       */  
  83.     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {  
  84.   
  85.         if (((e1.getX() - e2.getX()) > slideMinDistance) && Math.abs(velocityX) > slideMinVelocity) {    
  86.             Toast.makeText(this, "向左手势", Toast.LENGTH_SHORT).show();    
  87.         } else if (e2.getX() - e1.getX() > slideMinDistance && Math.abs(velocityX) > slideMinVelocity) {    
  88.         
  89.             // 切换Activity    
  90.             slideToGestureLeftActivity();  
  91.             Toast.makeText(this, "向右手势", Toast.LENGTH_SHORT).show();  
  92.         }  
  93.         
  94.         return false;    
  95.     }  
  96.   
  97.   
  98.     /* 
  99.       * <p>Title: onLongPress</p> 
  100.       * <p>Description: </p> 
  101.       * @param e 
  102.       * @see android.view.GestureDetector.OnGestureListener#onLongPress(android.view.MotionEvent) 
  103.       */  
  104.       
  105.       
  106.     public void onLongPress(MotionEvent e) {  
  107.   
  108.         // TODO Auto-generated method stub  
  109.           
  110.     }  
  111.   
  112.   
  113.     /* 
  114.       * <p>Title: onScroll</p> 
  115.       * <p>Description: </p> 
  116.       * @param e1 
  117.       * @param e2 
  118.       * @param distanceX 
  119.       * @param distanceY 
  120.       * @return 
  121.       * @see android.view.GestureDetector.OnGestureListener#onScroll(android.view.MotionEvent, android.view.MotionEvent, float, float) 
  122.       */  
  123.       
  124.       
  125.     public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {  
  126.   
  127.         // TODO Auto-generated method stub  
  128.         return false;  
  129.     }  
  130.   
  131.   
  132.     /* 
  133.       * <p>Title: onShowPress</p> 
  134.       * <p>Description: </p> 
  135.       * @param e 
  136.       * @see android.view.GestureDetector.OnGestureListener#onShowPress(android.view.MotionEvent) 
  137.       */  
  138.       
  139.       
  140.     public void onShowPress(MotionEvent e) {  
  141.   
  142.         // TODO Auto-generated method stub  
  143.           
  144.     }  
  145.   
  146.   
  147.     /* 
  148.       * <p>Title: onSingleTapUp</p> 
  149.       * <p>Description: </p> 
  150.       * @param e 
  151.       * @return 
  152.       * @see android.view.GestureDetector.OnGestureListener#onSingleTapUp(android.view.MotionEvent) 
  153.       */  
  154.       
  155.       
  156.     public boolean onSingleTapUp(MotionEvent e) {  
  157.   
  158.         // TODO Auto-generated method stub  
  159.         return false;  
  160.     }  
  161.   
  162.   
  163.     /* 
  164.       * <p>Title: onTouch</p> 
  165.       * <p>Description: </p> 
  166.       * @param v 
  167.       * @param event 
  168.       * @return 
  169.       * @see android.view.View.OnTouchListener#onTouch(android.view.View, android.view.MotionEvent) 
  170.       */  
  171.       
  172.       
  173.     public boolean onTouch(View v, MotionEvent event) {  
  174.   
  175.         // TODO Auto-generated method stub  
  176.         return gd.onTouchEvent(event);  
  177.     }  
  178.       
  179.     public boolean dispatchTouchEvent(MotionEvent ev) {  
  180.   
  181.         gd.onTouchEvent(ev);  
  182.           
  183.         // scroll.onTouchEvent(ev);  
  184.         return super.dispatchTouchEvent(ev);  
  185.     }   
  186. }  


(3)使用 ViewPager

posted @ 2017-10-05 12:05  欧阳平  阅读(2598)  评论(0编辑  收藏  举报