左右页面滑动
前言
通过左右滑动屏幕来切换页面,有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);
- }
- }