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如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值