Android 多页面左右滑动

前言

通过左右滑动屏幕来切换页面,有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 文件分别如下:

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

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



public class AnimLeftActivity extends Activity {

    private Button btnStart = null;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // 移除Title
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        setContentView(R.layout.left_layout);

        // 开始按钮
        btnStart = (Button) findViewById(R.id.btn_anim_left);
        
        /**
         * 开始测试按钮 的监听函数
         * 
         * */
        btnStart.setOnClickListener(new View.OnClickListener() {
			
			public void onClick(View view) {
				
				Intent i = new Intent(getApplicationContext(), AnimRightActivity.class);
				startActivity(i);
				
				// 设置切换动画,从右边进入,左边退出
		        overridePendingTransition(R.anim.right_activity_enter_from_right, R.anim.left_activity_out_to_left);
		        
				finish();			
			}
		});
    }
}
public class AnimRightActivity extends Activity {
	
    private Button btnStart = null;
	
	public void onCreate(Bundle savedInstanceState) {
		
		super.onCreate(savedInstanceState);
		
        // 移除Title
        requestWindowFeature(Window.FEATURE_NO_TITLE);
		
        setContentView(R.layout.right_layout);
        
        // 开始按钮
        btnStart = (Button) findViewById(R.id.btn_anim_right);
        
        /**
         * 开始测试按钮 的监听函数
         * 
         * */
        btnStart.setOnClickListener(new View.OnClickListener() {
			
			public void onClick(View view) {
				Intent i = new Intent(getApplicationContext(), AnimLeftActivity.class);
				startActivity(i);
				
				// 设置切换动画,从右边进入,左边退出
		        overridePendingTransition(R.anim.left_activity_enter_from_left, R.anim.right_activity_out_to_left);
		        
				finish();			}
		});
	}
}

(2)Activity 实现 OnTouchListener 和 OnGestureListener 接口

public class GestureLeftActivity extends Activity implements OnTouchListener, OnGestureListener {
    
	// 按钮
	private Button btnStart = null;
	
    // 监听左划动作
    private RelativeLayout rlLeft = null;
    private GestureDetector gd    = null;
    
    // 最小的水平有效划动距离和速度,超过该距离和速度才触发划动事件
    private int slideMinDistance = 20;  
    private int slideMinVelocity = 0;  
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // 移除Title
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        setContentView(R.layout.left_layout);
        
        btnStart = (Button) findViewById(R.id.btn_anim_left);
        btnStart.setText("");
        
        btnStart.setOnClickListener(new View.OnClickListener() {
			
			public void onClick(View v) {
		        Toast.makeText(GestureLeftActivity.this, "请向左滑动", Toast.LENGTH_SHORT).show();
			}
		});
        
        // 处理左划事件
        gd = new GestureDetector((OnGestureListener) this);    
        rlLeft = (RelativeLayout) findViewById(R.id.rl_left);    
        rlLeft.setOnTouchListener(this);    
        rlLeft.setLongClickable(true);
    }
    
    
    /**
     * 滑动到手写页面
      * @Title:       slideToAnalyser
      * @Description: TODO
      * @param        
      * @return       void
      * @throws
     */
    private void slideToGestureRightActivity() {
		Intent i = new Intent(getApplicationContext(), GestureRightActivity.class);
		startActivity(i);
		
		// 设置切换动画,从右边进入,左边退出
        overridePendingTransition(R.anim.right_activity_enter_from_right, R.anim.left_activity_out_to_left);
        
		finish();
    }
    
	/*
	  * <p>Title: onDown</p>
	  * <p>Description: </p>
	  * @param arg0
	  * @return
	  * @see android.view.GestureDetector.OnGestureListener#onDown(android.view.MotionEvent)
	  */
	public boolean onDown(MotionEvent arg0) {

		// TODO Auto-generated method stub
		return false;
	}


	/*
	  * <p>Title: onFling</p>
	  * <p>Description: </p>
	  * @param e1
	  * @param e2
	  * @param velocityX
	  * @param velocityY
	  * @return
	  * @see android.view.GestureDetector.OnGestureListener#onFling(android.view.MotionEvent, android.view.MotionEvent, float, float)
	  */
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

		if (((e1.getX() - e2.getX()) > slideMinDistance) && Math.abs(velocityX) > slideMinVelocity) {  
			  
	        // 切换Activity  
			slideToGestureRightActivity();
	        Toast.makeText(this, "向左手势", Toast.LENGTH_SHORT).show();  
	    } else if (e2.getX() - e1.getX() > slideMinDistance && Math.abs(velocityX) > slideMinVelocity) {  
	  
	        // 切换Activity  
	        // Intent intent = new Intent(ViewSnsActivity.this, UpdateStatusActivity.class);  
	        // startActivity(intent);  
	        Toast.makeText(this, "向右手势", Toast.LENGTH_SHORT).show();
	    }
	  
	    return false;  
	}


	/*
	  * <p>Title: onLongPress</p>
	  * <p>Description: </p>
	  * @param e
	  * @see android.view.GestureDetector.OnGestureListener#onLongPress(android.view.MotionEvent)
	  */
	
	
	public void onLongPress(MotionEvent e) {

		// TODO Auto-generated method stub
		
	}


	/*
	  * <p>Title: onScroll</p>
	  * <p>Description: </p>
	  * @param e1
	  * @param e2
	  * @param distanceX
	  * @param distanceY
	  * @return
	  * @see android.view.GestureDetector.OnGestureListener#onScroll(android.view.MotionEvent, android.view.MotionEvent, float, float)
	  */
	
	
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

		// TODO Auto-generated method stub
		return false;
	}


	/*
	  * <p>Title: onShowPress</p>
	  * <p>Description: </p>
	  * @param e
	  * @see android.view.GestureDetector.OnGestureListener#onShowPress(android.view.MotionEvent)
	  */
	
	
	public void onShowPress(MotionEvent e) {

		// TODO Auto-generated method stub
		
	}


	/*
	  * <p>Title: onSingleTapUp</p>
	  * <p>Description: </p>
	  * @param e
	  * @return
	  * @see android.view.GestureDetector.OnGestureListener#onSingleTapUp(android.view.MotionEvent)
	  */
	
	
	public boolean onSingleTapUp(MotionEvent e) {

		// TODO Auto-generated method stub
		return false;
	}


	/*
	  * <p>Title: onTouch</p>
	  * <p>Description: </p>
	  * @param v
	  * @param event
	  * @return
	  * @see android.view.View.OnTouchListener#onTouch(android.view.View, android.view.MotionEvent)
	  */
	
	
	public boolean onTouch(View v, MotionEvent event) {

		// TODO Auto-generated method stub
		return gd.onTouchEvent(event);
	}
	
	public boolean dispatchTouchEvent(MotionEvent ev) {

		gd.onTouchEvent(ev);
		
		// scroll.onTouchEvent(ev);
		return super.dispatchTouchEvent(ev);
	} 
}



public class GestureRightActivity extends Activity implements OnTouchListener, OnGestureListener {
    
	// 按钮
	private Button btnStart = null;
	
    // 监听左划动作
    private RelativeLayout rlRight = null;
    private GestureDetector gd    = null;
    
    // 最小的水平有效划动距离和速度,超过该距离和速度才触发划动事件
    private int slideMinDistance = 20;  
    private int slideMinVelocity = 0;  
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // 移除Title
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        setContentView(R.layout.right_layout);
        
        btnStart = (Button) findViewById(R.id.btn_anim_right);
        btnStart.setText("");
        
        btnStart.setOnClickListener(new View.OnClickListener() {
			
			public void onClick(View v) {
		        Toast.makeText(GestureRightActivity.this, "请向右滑动", Toast.LENGTH_SHORT).show();
			}
		});
        
        // 处理左划事件
        gd = new GestureDetector((OnGestureListener) this);    
        rlRight = (RelativeLayout) findViewById(R.id.rl_right);    
        rlRight.setOnTouchListener(this);    
        rlRight.setLongClickable(true);
    }
    
    
    /**
     * 滑动到手写页面
      * @Title:       slideToAnalyser
      * @Description: TODO
      * @param        
      * @return       void
      * @throws
     */
    private void slideToGestureLeftActivity() {
		Intent i = new Intent(getApplicationContext(), GestureLeftActivity.class);
		startActivity(i);
		
		// 设置切换动画,从右边进入,左边退出
        overridePendingTransition(R.anim.left_activity_enter_from_left, R.anim.right_activity_out_to_left);
        
		finish();
    }
    
	/*
	  * <p>Title: onDown</p>
	  * <p>Description: </p>
	  * @param arg0
	  * @return
	  * @see android.view.GestureDetector.OnGestureListener#onDown(android.view.MotionEvent)
	  */
	public boolean onDown(MotionEvent arg0) {

		// TODO Auto-generated method stub
		return false;
	}


	/*
	  * <p>Title: onFling</p>
	  * <p>Description: </p>
	  * @param e1
	  * @param e2
	  * @param velocityX
	  * @param velocityY
	  * @return
	  * @see android.view.GestureDetector.OnGestureListener#onFling(android.view.MotionEvent, android.view.MotionEvent, float, float)
	  */
	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

		if (((e1.getX() - e2.getX()) > slideMinDistance) && Math.abs(velocityX) > slideMinVelocity) {  
	        Toast.makeText(this, "向左手势", Toast.LENGTH_SHORT).show();  
	    } else if (e2.getX() - e1.getX() > slideMinDistance && Math.abs(velocityX) > slideMinVelocity) {  
	  
	        // 切换Activity  
			slideToGestureLeftActivity();
	        Toast.makeText(this, "向右手势", Toast.LENGTH_SHORT).show();
	    }
	  
	    return false;  
	}


	/*
	  * <p>Title: onLongPress</p>
	  * <p>Description: </p>
	  * @param e
	  * @see android.view.GestureDetector.OnGestureListener#onLongPress(android.view.MotionEvent)
	  */
	
	
	public void onLongPress(MotionEvent e) {

		// TODO Auto-generated method stub
		
	}


	/*
	  * <p>Title: onScroll</p>
	  * <p>Description: </p>
	  * @param e1
	  * @param e2
	  * @param distanceX
	  * @param distanceY
	  * @return
	  * @see android.view.GestureDetector.OnGestureListener#onScroll(android.view.MotionEvent, android.view.MotionEvent, float, float)
	  */
	
	
	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

		// TODO Auto-generated method stub
		return false;
	}


	/*
	  * <p>Title: onShowPress</p>
	  * <p>Description: </p>
	  * @param e
	  * @see android.view.GestureDetector.OnGestureListener#onShowPress(android.view.MotionEvent)
	  */
	
	
	public void onShowPress(MotionEvent e) {

		// TODO Auto-generated method stub
		
	}


	/*
	  * <p>Title: onSingleTapUp</p>
	  * <p>Description: </p>
	  * @param e
	  * @return
	  * @see android.view.GestureDetector.OnGestureListener#onSingleTapUp(android.view.MotionEvent)
	  */
	
	
	public boolean onSingleTapUp(MotionEvent e) {

		// TODO Auto-generated method stub
		return false;
	}


	/*
	  * <p>Title: onTouch</p>
	  * <p>Description: </p>
	  * @param v
	  * @param event
	  * @return
	  * @see android.view.View.OnTouchListener#onTouch(android.view.View, android.view.MotionEvent)
	  */
	
	
	public boolean onTouch(View v, MotionEvent event) {

		// TODO Auto-generated method stub
		return gd.onTouchEvent(event);
	}
	
	public boolean dispatchTouchEvent(MotionEvent ev) {

		gd.onTouchEvent(ev);
		
		// scroll.onTouchEvent(ev);
		return super.dispatchTouchEvent(ev);
	} 
}


(3)使用 ViewPager

待续。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值