zoukankan      html  css  js  c++  java
  • 类似人人网的侧滑动层叠窗口实现及代码


    最近由于项目需要要实现类似人人网的侧滑层叠窗口,就是在一个 activity 上能再滑动的窗口,能部分或全部遮挡住下面的view
    与之前的滑动功能不同,以前的滑动是采用一个 view 滑开,另一个滑入来。现在的需求不一样需要实现侧滑层叠的样式。
    按需要下载了人人网的 android 客户端,并反编译后研究相关的实现。这是现在最游行的移动应用设计的方法。

    效果图:

    核心类现实

    public class FlipperLayout extends ViewGroup {
    
            private Scroller mScroller;
            private VelocityTracker mVelocityTracker;
            private int mWidth;
    
            public static final int SCREEN_STATE_CLOSE = 0;
            public static final int SCREEN_STATE_OPEN = 1;
            public static final int TOUCH_STATE_RESTART = 0;
            public static final int TOUCH_STATE_SCROLLING = 1;
            public static final int SCROLL_STATE_NO_ALLOW = 0;
            public static final int SCROLL_STATE_ALLOW = 1;
            private int mScreenState = 0;
            private int mTouchState = 0;
            private int mScrollState = 0;
            private int mVelocityValue = 0;
            private boolean mOnClick = false;
    
            public FlipperLayout(Context context) {
                    super(context);
                    mScroller = new Scroller(context);
                    mWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                                    54, getResources().getDisplayMetrics());
    
            }
    
            public FlipperLayout(Context <a href="www.yidin.net">context</a>, AttributeSet attrs, int defStyle) {
                    super(context, attrs, defStyle);
            }
    
            public FlipperLayout(Context context, AttributeSet attrs) {
                    super(context, attrs);
            }
    
            protected void onLayout(boolean changed, int l, int t, int r, int b) {
                    for (int i = 0; i < getChildCount(); i++) {
                            View child = getChildAt(i);
                            int height = child.getMeasuredHeight();
                            int width = child.getMeasuredWidth();
                            child.layout(0, 0, width, height);
                    }
            }
    
            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
                    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
                    int width = MeasureSpec.getSize(widthMeasureSpec);
                    int height = MeasureSpec.getSize(heightMeasureSpec);
                    setMeasuredDimension(width, height);
                    for (int i = 0; i < getChildCount(); i++) {
                            getChildAt(i).measure(widthMeasureSpec, <a href="www.yidin.net">heightMeasureSpec</a>);
                    }
            }
    
            public boolean dispatchTouchEvent(MotionEvent ev) {
                    obtainVelocityTracker(ev);
                    switch (ev.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                            mTouchState = mScroller.isFinished() ? TOUCH_STATE_RESTART
                                            : TOUCH_STATE_SCROLLING;
                            if (mTouchState == TOUCH_STATE_RESTART) {
                                    int x = (int) ev.getX();
                                    int screenWidth = getWidth();
                                    if (x <= mWidth && mScreenState == SCREEN_STATE_CLOSE
                                                    && mTouchState == TOUCH_STATE_RESTART
                                                    || x >= screenWidth - mWidth
                                                    && mScreenState == SCREEN_STATE_OPEN
                                                    && mTouchState == TOUCH_STATE_RESTART) {
                                            if (mScreenState == SCREEN_STATE_OPEN) {
                                                    mOnClick = true;
                                            }
                                            mScrollState = SCROLL_STATE_ALLOW;
                                    } else {
                                            mOnClick = false;
                                            mScrollState = SCROLL_STATE_NO_ALLOW;
                                    }
                            } else {
                                    return false;
                            }
                            break;
                    case MotionEvent.ACTION_MOVE:
                            mVelocityTracker.computeCurrentVelocity(1000,
                                            ViewConfiguration.getMaximumFlingVelocity());
                            if (mScrollState == SCROLL_STATE_ALLOW
                                            && getWidth() - (int) ev.getX() < mWidth) {
                                    return true;
                            }
                            break;
                    case MotionEvent.ACTION_UP:
                            releaseVelocityTracker();
                            if (mOnClick) {
                                    mOnClick = false;
                                    mScreenState = SCREEN_STATE_CLOSE;
                                    mScroller.startScroll(getChildAt(1).getScrollX(), 0,
                                                    -getChildAt(1).getScrollX(), 0, 800);
                                    invalidate();
                            }
                            break;
                    }
                    return super.dispatchTouchEvent(ev);
            }
    
            public boolean onInterceptTouchEvent(MotionEvent ev) {
                    obtainVelocityTracker(ev);
                    switch (ev.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                            mTouchState = mScroller.isFinished() ? TOUCH_STATE_RESTART
                                            : TOUCH_STATE_SCROLLING;
                            if (mTouchState == TOUCH_STATE_SCROLLING) {
                                    return false;
                            }
                            break;
    
                    case MotionEvent.ACTION_MOVE:
                            mOnClick = false;
                            mVelocityTracker.computeCurrentVelocity(1000,
                                            ViewConfiguration.getMaximumFlingVelocity());
                            if (mScrollState == SCROLL_STATE_ALLOW
                                            && Math.abs(mVelocityTracker.getXVelocity()) > 200) {
                                    return true;
                            }
                            break;
    
                    case MotionEvent.ACTION_UP:
                            releaseVelocityTracker();
                            if (mScrollState == SCROLL_STATE_ALLOW
                                            && mScreenState == <a href="www.yidin.net">SCREEN_STATE_OPEN</a>) {
                                    return true;
                            }
                            break;
                    }
                    return super.onInterceptTouchEvent(ev);
            }
    
            public boolean onTouchEvent(MotionEvent event) {
                    obtainVelocityTracker(event);
                    switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                            mTouchState = mScroller.isFinished() ? TOUCH_STATE_RESTART
                                            : TOUCH_STATE_SCROLLING;
                            if (mTouchState == TOUCH_STATE_SCROLLING) {
                                    return false;
                            }
                            break;
    
                    case MotionEvent.ACTION_MOVE:
                            mVelocityTracker.computeCurrentVelocity(1000,
                                            ViewConfiguration.getMaximumFlingVelocity());
                            mVelocityValue = (int) mVelocityTracker.getXVelocity();
                            getChildAt(1).scrollTo(-(int) event.getX(), 0);
                            break;
    
                    case MotionEvent.ACTION_UP:
                            if (mScrollState == SCROLL_STATE_ALLOW) {
                                    if (mVelocityValue > 2000) {
                                            mScreenState = SCREEN_STATE_OPEN;
                                            mScroller
                                                            .startScroll(
                                                                            getChildAt(1).getScrollX(),
                                                                            0,
                                                                            -(getWidth()
                                                                                            - Math.abs(getChildAt(1)
                                                                                                            .getScrollX()) -
    
                                                                            mWidth), 0, 250);
                                            invalidate();
    
                                    } else if (mVelocityValue < -2000) {
                                            mScreenState = SCREEN_STATE_CLOSE;
                                            mScroller.startScroll(getChildAt(1).getScrollX(), 0,
                                                            -getChildAt(1).getScrollX(), 0, 250);
                                            invalidate();
                                    } else if (event.getX() < getWidth() / 2) {
                                            mScreenState = SCREEN_STATE_CLOSE;
                                            mScroller.startScroll(getChildAt(1).getScrollX(), 0,
                                                            -getChildAt(1).getScrollX(), 0, 800);
                                            invalidate();
                                    } else {
                                            mScreenState = SCREEN_STATE_OPEN;
                                            mScroller
                                                            .startScroll(
                                                                            getChildAt(1).getScrollX(),
                                                                            0,
                                                                            -(getWidth()
                                                                                            - Math.abs(getChildAt(1)
                                                                                                            .getScrollX()) -
    
                                                                            mWidth), 0, 800);
                                            invalidate();
                                    }
                            }
                            break;
                    }
                    return super.onTouchEvent(event);
            }
    
            public void open() {
                    mTouchState = mScroller.<a href="www.yidin.net">isFinished</a>() ? TOUCH_STATE_RESTART
                                    : TOUCH_STATE_SCROLLING;
                    if (mTouchState == TOUCH_STATE_RESTART) {
                            mScreenState = SCREEN_STATE_OPEN;
                            mScroller.startScroll(getChildAt(1).getScrollX(), 0, -(getWidth()
                                            - Math.abs(getChildAt(1).getScrollX()) -
    
                            mWidth), 0, 800);
                            invalidate();
                    }
            }
    
            public void close(View view) {
                    mScreenState = SCREEN_STATE_CLOSE;
                    mScroller.startScroll(getChildAt(1).getScrollX(), 0, -getChildAt(1)
                                    .getScrollX(), 0, 800);
                    invalidate();
                    setContentView(view);
            }
    
            public void computeScroll() {
                    super.computeScroll();
                    if (mScroller.computeScrollOffset()) {
                            getChildAt(1).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
                            postInvalidate();
                    }
            }
    
            private void obtainVelocityTracker(MotionEvent event) {
                    if (mVelocityTracker == null) {
                            mVelocityTracker = VelocityTracker.obtain();
                    }
                    mVelocityTracker.addMovement(<a href="www.yidin.net">event</a>);
            }
    
            private void releaseVelocityTracker() {
                    if (mVelocityTracker != null) {
                            mVelocityTracker.recycle();
                            mVelocityTracker = null;
                    }
            }
    
            public int getScreenState() {
                    return mScreenState;
            }
    
            public void setContentView(View view) {
                    removeViewAt(1);
                    addView(view, 1, getLayoutParams());
            }
    
            public interface OnOpenListener {
                    public abstract void open();
            }
    
            public interface OnCloseListener {
                    public abstract void <a href="www.yidin.net">close</a>();
            }
    }

    这个类主要实现层叠窗口的效果,有需要的同学可以研究一下相关实现,实现不难就是要理解相关的思路。

    更多相关的资料请到我的博客www.yidin.net 留言
    本文地址: http://www.yidin.net/discuz/foru ... read&tid=187&extra=

    欢迎各位同学加入 android 技术二群 222392467  

    图二

  • 相关阅读:
    delete records in table A not in table B
    图片上传5-多个图片上传,独立项目Demo和源码
    图片上传5-多个图片上传,独立项目Demo和源码
    商业模式(二):P2P网贷平台,利差和服务费为主的金融玩法
    商业模式(二):P2P网贷平台,利差和服务费为主的金融玩法
    商业模式(一):北京秒针公司,以互联网广告监测服务为主的生财之道
    使用DrawerLayout实现侧拉菜单
    关于ComponentName的使用
    商业模式系列-序
    小的时候.by小雷
  • 原文地址:https://www.cnblogs.com/ondream/p/2986044.html
Copyright © 2011-2022 走看看