Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android側滑菜單完整詳細示例(精裝版)

Android側滑菜單完整詳細示例(精裝版)

編輯:關於Android編程

MainActivity如下:
package cn.patience7;

import android.os.AsyncTask;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnPreDrawListener;
import android.widget.RelativeLayout;
import android.app.Activity;
import android.content.Context;

/**
 * Demo描述: 
 * 滑動菜單SlidingMenu完整詳細示例
 * 
 * 布局文件:
 * 采用相對布局,兩個界面是重疊在一起的,分別為aboveView和belowView.
 * 
 * 實現原理:
 * 對aboveView的Touch事件進行監聽
 * 即mBboveView.setOnTouchListener(new TouchListenerImpl())
 * 在TouchListenerImpl中:
 * 1 ACTION_UP時將aboveView彈回到屏幕的左右兩側
 * 2 除ACTION_UP之外的Action交給手勢GestureDetector處理
 * 
 * 所以通過aboveView的移動來遮掩或者顯示belowView,從而達到 側滑菜單的效果
 * 
 * 
 * 備注說明:
 * 該Demo與前面兩個側滑菜單實現原理是差不多但在代碼實現上使用了GestureDetector
 */
public class MainActivity extends Activity {
	private View mAboveView;
	private View mBelowView;
	private float scrollX = 0;
	private Context mContext;
	private int screenWidth = 0;
	private boolean isMeasured = false;
	private int MAX_SCROLL_DISTANCE = 0;
	private GestureDetector mGestureDetector;
	private GestureListenerImpl mGestureListenerImpl;
	private SlowlyMoveAsyncTask mSlowlyMoveAsyncTask;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		initView();
	}

	private void initView() {
		mContext = this;
		mGestureListenerImpl = new GestureListenerImpl();
		mGestureDetector = new GestureDetector(mContext, mGestureListenerImpl);
		mGestureDetector.setIsLongpressEnabled(false);
		mAboveView = findViewById(R.id.aboveLinearLayout);
		mAboveView.setOnTouchListener(new TouchListenerImpl());
		mBelowView = findViewById(R.id.belowLinearLayout);
		initData();
	}

	/**
	 * 1 將aboveView的寬度設置為屏幕的寬度,從而完全遮掩belowView
	 * 2 MAX_SCROLL_DISTANCE為aboveView向屏幕左側的最大滑動距離
	 */
	private void initData() {
		ViewTreeObserver viewTreeObserver = mAboveView.getViewTreeObserver();
		viewTreeObserver.addOnPreDrawListener(new OnPreDrawListener() {
			@Override
			public boolean onPreDraw() {
				if (!isMeasured) {
					screenWidth = getWindowManager().getDefaultDisplay().getWidth();
					RelativeLayout.LayoutParams aboveViewLayoutParams
					=(RelativeLayout.LayoutParams) mAboveView.getLayoutParams();
					aboveViewLayoutParams.width = screenWidth;
					mAboveView.setLayoutParams(aboveViewLayoutParams);
					MAX_SCROLL_DISTANCE = mBelowView.getWidth();
					isMeasured = true;
				}
				return true;
			}
		});
	}

	private class TouchListenerImpl implements OnTouchListener {
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			if (event.getAction() == MotionEvent.ACTION_UP) {
				RelativeLayout.LayoutParams aboveViewLayoutParams
				=(RelativeLayout.LayoutParams) mAboveView.getLayoutParams();
				if (aboveViewLayoutParams.leftMargin > (-screenWidth / 2)) {
					// 手指往左滑時,未及屏幕一半時抬起.歸位
					mSlowlyMoveAsyncTask = new SlowlyMoveAsyncTask();
					mSlowlyMoveAsyncTask.execute(20);
				} else {
					// 手指往左滑時,超過屏幕一半時抬起.歸位
					mSlowlyMoveAsyncTask = new SlowlyMoveAsyncTask();
					mSlowlyMoveAsyncTask.execute(-20);
				}
			}
			return mGestureDetector.onTouchEvent(event);
		}
	}

	private class GestureListenerImpl implements GestureDetector.OnGestureListener {
		@Override
		public boolean onDown(MotionEvent arg0) {
			return true;
		}

		@Override
		public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,float arg3) {
			return false;
		}

		@Override
		public void onLongPress(MotionEvent arg0) {
		}

		@Override
		public boolean onScroll(MotionEvent arg0, MotionEvent arg1,float distanceX, float distanceY) {
			scrollX = scrollX + distanceX;
			RelativeLayout.LayoutParams aboveViewLayoutParams
			=(RelativeLayout.LayoutParams) mAboveView.getLayoutParams();
			aboveViewLayoutParams.leftMargin = (int) (aboveViewLayoutParams.leftMargin - scrollX);
			// 手指往右邊滑動的極限,防止越界
			if (aboveViewLayoutParams.leftMargin >= 0) {
				aboveViewLayoutParams.leftMargin = 0;
			}
			// 手指往左邊滑動的極限,防止越界
			if (-aboveViewLayoutParams.leftMargin >= MAX_SCROLL_DISTANCE) {
				aboveViewLayoutParams.leftMargin = -MAX_SCROLL_DISTANCE;
			}
			mAboveView.setLayoutParams(aboveViewLayoutParams);
			return false;
		}

		@Override
		public void onShowPress(MotionEvent motionEvent) {

		}

		@Override
		public boolean onSingleTapUp(MotionEvent motionEvent) {
			return false;
		}
	}

	// 以下為異步任務,負責處理手指抬起時布局向屏幕左右兩側彈回
	private class SlowlyMoveAsyncTask extends AsyncTask {
		@Override
		protected Void doInBackground(Integer... params) {
			RelativeLayout.LayoutParams aboveViewLayoutParams
			= (RelativeLayout.LayoutParams) mAboveView.getLayoutParams();
			int leftMargin = aboveViewLayoutParams.leftMargin;
			// 需要移動的次數
			int move_times = 0;
			// 總共需要彈回的距離
			int all_move_distance = 0;
			// 每次彈回的距離
			int every_move_distance = Math.abs(params[0]);

			// 往屏幕右邊移動
			if (params[0] > 0) {
				all_move_distance = Math.abs(leftMargin);
				// 往屏幕左邊移動
			} else {
				all_move_distance = MAX_SCROLL_DISTANCE - Math.abs(leftMargin);
			}

			// 計算需要移動的次數
			if (all_move_distance % every_move_distance == 0) {
				move_times = all_move_distance / every_move_distance;
			} else {
				move_times = all_move_distance / every_move_distance + 1;
			}

			System.out.println("--> all_move_distance=" + all_move_distance);
			System.out.println("--> every_move_distance=" + every_move_distance);
			System.out.println("--> move_times=" + move_times);

			// 移動的過程
			for (int i = 0; i < move_times; i++) {
				publishProgress(params[0]);
				try {
					Thread.sleep(20);
				} catch (Exception e) {
				}
			}
			return null;
		}

		@Override
		protected void onProgressUpdate(Integer... values) {
			super.onProgressUpdate(values);
			int every_move_distance = values[0];
			RelativeLayout.LayoutParams aboveViewLayoutParams
			= (RelativeLayout.LayoutParams) mAboveView.getLayoutParams();
			if (every_move_distance > 0) {
				if (aboveViewLayoutParams.leftMargin < 0) {
					aboveViewLayoutParams.leftMargin += every_move_distance;
					// 處理最後一次滑動後可能越界的情況
					if (aboveViewLayoutParams.leftMargin > 0) {
						aboveViewLayoutParams.leftMargin = 0;
					}
					mAboveView.setLayoutParams(aboveViewLayoutParams);
				}
			} else {
				if (aboveViewLayoutParams.leftMargin > (-MAX_SCROLL_DISTANCE)) {
					aboveViewLayoutParams.leftMargin -= (-every_move_distance);
					// 處理最後一次滑動後可能越界的情況
					if (aboveViewLayoutParams.leftMargin < -MAX_SCROLL_DISTANCE) {
						aboveViewLayoutParams.leftMargin = -MAX_SCROLL_DISTANCE;
					}
					mAboveView.setLayoutParams(aboveViewLayoutParams);
				}
			}
		}
	}
}

main.xml如下:


    

        
    

    

        
    



  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved