android 根据手势滚动菜单 SlidingMenu

public class SlidingMenu extends RelativeLayout {

    private View mCenterView;
    private View mLeftView;
    private View mRightView;
    private RelativeLayout mBgShade;
    private int mScreenWidth;
    private int mScreenHeight;
    private Context mContext;
    private Scroller mScroller;
    private VelocityTracker mVelocityTracker;
    private int mTouchSlop;
    private float mLastMotionX;
    private float mLastMotionY;
    private static final int VELOCITY = 50;
    private boolean mIsBeingDragged = true;
    private boolean isCanSlideLeft = true;
    private boolean isCanSlideRight = false;
    private boolean isHasClickLeft = true;
    private boolean isHasClickRight = false;

    public SlidingMenu(Context context) {
        super(context);
        init(context);
    }

    private void init(Context context) {

        mContext = context;
        // 背景阴影
        mBgShade = new RelativeLayout(context);
        mScroller = new Scroller(getContext());
        mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
        WindowManager windowManager = ((Activity) context).getWindow().getWindowManager();
        Display display = windowManager.getDefaultDisplay();
        mScreenWidth = display.getWidth();
        mScreenHeight = display.getHeight();
        LayoutParams bgParams = new LayoutParams(mScreenWidth, mScreenHeight);
        bgParams.addRule(RelativeLayout.CENTER_IN_PARENT);
        mBgShade.setLayoutParams(bgParams);

    }

    public SlidingMenu(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public SlidingMenu(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    public void addViews(View left, View center, View right) {
        setLeftView(left);
        setRightView(right);
        setCenterView(center);
    }

    public void setLeftView(View view) {
        LayoutParams behindParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.FILL_PARENT);
        addView(view, behindParams);
        mLeftView = view;
    }

    public void setRightView(View view) {
        LayoutParams behindParams = new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.FILL_PARENT);
        behindParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
        addView(view, behindParams);
        mRightView = view;
    }

    public void setCenterView(View view) {
        LayoutParams aboveParams = new LayoutParams(LayoutParams.FILL_PARENT,
                LayoutParams.FILL_PARENT);

        LayoutParams bgParams = new LayoutParams(mScreenWidth, mScreenHeight);
        bgParams.addRule(RelativeLayout.CENTER_IN_PARENT);

        View bgShadeContent = new View(mContext);
        bgShadeContent.setBackgroundDrawable(getResources().getDrawable(R.drawable.shade_bg));
        mBgShade.addView(bgShadeContent, bgParams);

        addView(mBgShade, bgParams);

        addView(view, aboveParams);
        mCenterView = view;
        mCenterView.bringToFront();
    }

    @Override
    public void scrollTo(int x, int y) {
        super.scrollTo(x, y);
        postInvalidate();
    }

    @Override
    public void computeScroll() {
        if (!mScroller.isFinished()) {
            if (mScroller.computeScrollOffset()) {
                int oldX = mCenterView.getScrollX();
                int oldY = mCenterView.getScrollY();
                int x = mScroller.getCurrX();
                int y = mScroller.getCurrY();
                if (oldX != x || oldY != y) {
                    if (mCenterView != null) {
                        mCenterView.scrollTo(x, y);
                        if (x < 0)
                            mBgShade.scrollTo(x + 20, y);// 背景阴影右偏
                        else
                            mBgShade.scrollTo(x - 20, y);// 背景阴影左偏
                    }
                }
                invalidate();
            }
        }
    }

    private boolean canSlideLeft = true;
    private boolean canSlideRight = false;

    public void setCanSliding(boolean left, boolean right) {
        canSlideLeft = left;
        canSlideRight = right;
    }

    /* 拦截touch事件 */
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        final int action = ev.getAction();
        final float x = ev.getX();
        final float y = ev.getY();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mLastMotionX = x;
                mLastMotionY = y;
                mIsBeingDragged = false;
                if (canSlideLeft) {
                    mLeftView.setVisibility(View.VISIBLE);
                    if (null != mRightView) {
                        mRightView.setVisibility(View.INVISIBLE);
                    }
                }
                if (canSlideRight) {
                    mLeftView.setVisibility(View.INVISIBLE);
                    if (null != mRightView) {
                        mRightView.setVisibility(View.VISIBLE);
                    }
                }
                break;

            case MotionEvent.ACTION_MOVE:
                final float dx = x - mLastMotionX;
                final float xDiff = Math.abs(dx);
                final float yDiff = Math.abs(y - mLastMotionY);
                if (xDiff > mTouchSlop && xDiff > yDiff) {
                    if (canSlideLeft) {
                        float oldScrollX = mCenterView.getScrollX();
                        if (oldScrollX < 0) {
                            mIsBeingDragged = true;
                            mLastMotionX = x;
                        } else {
                            if (dx > 0) {
                                mIsBeingDragged = true;
                                mLastMotionX = x;
                            }
                        }

                    } else if (canSlideRight) {
                        float oldScrollX = mCenterView.getScrollX();
                        if (oldScrollX > 0) {
                            mIsBeingDragged = true;
                            mLastMotionX = x;
                        } else {
                            if (dx < 0) {
                                mIsBeingDragged = true;
                                mLastMotionX = x;
                            }
                        }
                    }
                }
                break;
        }
        return mIsBeingDragged;
    }

    /* 处理拦截后的touch事件 */
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(ev);

        final int action = ev.getAction();
        final float x = ev.getX();
        final float y = ev.getY();

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                if (!mScroller.isFinished()) {
                    mScroller.abortAnimation();
                }
                mLastMotionX = x;
                mLastMotionY = y;
                if (mCenterView.getScrollX() == -getMenuViewWidth()
                        && mLastMotionX < getMenuViewWidth()) {
                    return false;
                }

                if (mCenterView.getScrollX() == getDetailViewWidth()
                        && mLastMotionX > getMenuViewWidth()) {
                    return false;
                }

                break;
            case MotionEvent.ACTION_MOVE:
                if (mIsBeingDragged) {
                    final float deltaX = mLastMotionX - x;
                    mLastMotionX = x;
                    float oldScrollX = mCenterView.getScrollX();
                    float scrollX = oldScrollX + deltaX;
                    if (canSlideLeft) {
                        if (scrollX > 0)
                            scrollX = 0;
                    }
                    if (canSlideRight) {
                        if (scrollX < 0)
                            scrollX = 0;
                    }
                    if (deltaX < 0 && oldScrollX < 0) { // left view
                        final float leftBound = 0;
                        final float rightBound = -getMenuViewWidth();
                        if (scrollX > leftBound) {
                            scrollX = leftBound;
                        } else if (scrollX < rightBound) {
                            scrollX = rightBound;
                        }
                    } else if (deltaX > 0 && oldScrollX > 0) { // right view
                        final float rightBound = getDetailViewWidth();
                        final float leftBound = 0;
                        if (scrollX < leftBound) {
                            scrollX = leftBound;
                        } else if (scrollX > rightBound) {
                            scrollX = rightBound;
                        }
                    }
                    if (mCenterView != null) {
                        mCenterView.scrollTo((int) scrollX, mCenterView.getScrollY());
                        if (scrollX < 0)
                            mBgShade.scrollTo((int) scrollX + 20, mCenterView.getScrollY());
                        else
                            mBgShade.scrollTo((int) scrollX - 20, mCenterView.getScrollY());
                    }
                }
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if (mIsBeingDragged) {
                    final VelocityTracker velocityTracker = mVelocityTracker;
                    velocityTracker.computeCurrentVelocity(100);
                    float xVelocity = velocityTracker.getXVelocity();// 滑动的速度
                    int oldScrollX = mCenterView.getScrollX();
                    int dx = 0;
                    if (oldScrollX <= 0 && canSlideLeft) {// left view
                        if (xVelocity > VELOCITY) {
                            dx = -getMenuViewWidth() - oldScrollX;
                        } else if (xVelocity < -VELOCITY) {
                            dx = -oldScrollX;
                            if (isHasClickLeft) {
                                isHasClickLeft = false;
                                setCanSliding(isCanSlideLeft, isCanSlideRight);
                            }
                        } else if (oldScrollX < -getMenuViewWidth() / 2) {
                            dx = -getMenuViewWidth() - oldScrollX;
                        } else if (oldScrollX >= -getMenuViewWidth() / 2) {
                            dx = -oldScrollX;
                            if (isHasClickLeft) {
                                isHasClickLeft = false;
                                setCanSliding(isCanSlideLeft, isCanSlideRight);
                            }
                        }
                    }
                    if (oldScrollX >= 0 && canSlideRight) {
                        if (xVelocity < -VELOCITY) {
                            dx = getDetailViewWidth() - oldScrollX;
                        } else if (xVelocity > VELOCITY) {
                            dx = -oldScrollX;
                            if (isHasClickRight) {
                                isHasClickRight = false;
                                setCanSliding(isCanSlideLeft, isCanSlideRight);
                            }
                        } else if (oldScrollX > getDetailViewWidth() / 2) {
                            dx = getDetailViewWidth() - oldScrollX;
                        } else if (oldScrollX <= getDetailViewWidth() / 2) {
                            dx = -oldScrollX;
                            if (isHasClickRight) {
                                isHasClickRight = false;
                                setCanSliding(isCanSlideLeft, isCanSlideRight);
                            }
                        }
                    }
                    smoothScrollTo(dx);
                }
                break;
        }
        return true;
    }

    private int getMenuViewWidth() {
        if (mLeftView == null) {
            return 0;
        }
        return mLeftView.getWidth();
    }

    private int getDetailViewWidth() {
        if (mRightView == null) {
            return 0;
        }
        return mRightView.getWidth();
    }

    private void smoothScrollTo(int dx) {
        int duration = 500;
        int oldScrollX = mCenterView.getScrollX();
        mScroller.startScroll(oldScrollX, mCenterView.getScrollY(), dx, mCenterView.getScrollY(),
                duration);
        invalidate();
    }

    public boolean isCenterViewShow() {
        int scrollX = mCenterView.getScrollX();
        if (scrollX == 0) {
            return true;
        }
        return false;
    }

    /*
     * 显示左侧边的view
     */
    public void showLeftView() {
        int menuWidth = mLeftView.getWidth();
        int oldScrollX = mCenterView.getScrollX();
        if (oldScrollX == 0) {
            mLeftView.setVisibility(View.VISIBLE);
            if (null != mRightView) {
                mRightView.setVisibility(View.INVISIBLE);
            }
            smoothScrollTo(-menuWidth);
            isCanSlideLeft = canSlideLeft;
            isCanSlideRight = canSlideRight;
            isHasClickLeft = true;
            setCanSliding(true, false);
        } else if (oldScrollX == -menuWidth) {
            smoothScrollTo(menuWidth);
            if (isHasClickLeft) {
                isHasClickLeft = false;
                setCanSliding(isCanSlideLeft, isCanSlideRight);
            }
        }
    }

    /* 显示右侧边的view */
    public void showRightView() {
        int menuWidth = getDetailViewWidth();
        int oldScrollX = mCenterView.getScrollX();
        if (oldScrollX == 0) {
            mLeftView.setVisibility(View.INVISIBLE);
            if (null != mRightView) {
                mRightView.setVisibility(View.VISIBLE);
            }
            smoothScrollTo(menuWidth);
            isCanSlideLeft = canSlideLeft;
            isCanSlideRight = canSlideRight;
            isHasClickRight = true;
            setCanSliding(false, true);
        } else if (oldScrollX == menuWidth) {
            smoothScrollTo(-menuWidth);
            if (isHasClickRight) {
                isHasClickRight = false;
                setCanSliding(isCanSlideLeft, isCanSlideRight);
            }
        }
    }

}
 

 

activity初始化:

protected void initView() {
        slidingMenuView = (MainSlidingMenuView) findViewById(R.id.slidingMenuView);
        slidingMenuView.setMenuView(getLayoutInflater().inflate(
                R.layout.function_grid_frame, null));
        slidingMenuView.setContentView(getLayoutInflater().inflate(
                R.layout.content_container, null));
    }

 

public void showLeft() {
        slidingMenuView.showMenuView();
    }

 

主页面:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    >
    
    
     <widget.MainSlidingMenuView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/slidingMenuView"
         >
    </widget.MainSlidingMenuView>
    
</RelativeLayout>

 

菜单布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/menu_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</FrameLayout>

 

页面内容部分布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/content_container"
    >
</FrameLayout>

 

菜单和内容部分用fragment填充

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值