Android侧滑菜单完整详细示例(精装版)
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<Integer, Integer, Void> { @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如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:id="@+id/belowLinearLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_marginLeft="50dip" > <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:scaleType="fitXY" android:src="@drawable/a" /> </LinearLayout> <LinearLayout android:id="@+id/aboveLinearLayout" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <ImageView android:id="@+id/imageView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scaleType="fitXY" android:src="@drawable/b" /> </LinearLayout> </RelativeLayout>
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。