左右頁面滑動
阿新 • • 發佈:2017-10-05
velocity lns xtend tap utf nis desc cells context
[java] view plain copy
前言
通過左右滑動屏幕來切換頁面,有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
- <?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>
[html] view plain copy
- <?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 接口
[java] view plain copy- 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);
- }
- }
[java] view plain copy
- 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
左右頁面滑動