美文网首页
自定义View-22.酷狗侧滑菜单效果

自定义View-22.酷狗侧滑菜单效果

作者: zsj1225 | 来源:发表于2018-07-08 17:35 被阅读41次

    效果如下

    TIM图片20180708173517.gif

    1.1继承自定义 HorizontalScrollView , 写个好两个布局(menu , content).

    public class SlidingMenu extends HorizontalScrollView {
    }
    
    <?xml version="1.0" encoding="utf-8"?>
    <com.zsj.slidingmenu.SlidingMenu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/home_menu_bg"
        tools:context="com.zsj.slidingmenu.MainActivity">
    
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal">
    
            <include layout="@layout/layout_home_menu" />
    
    
            <include layout="@layout/layout_home_content" />
    
        </LinearLayout>
    
    
    </com.zsj.slidingmenu.SlidingMenu>
    

    运行起来界面异常,宽度显示不对.

    1.2 重新指定宽度.

      //宽度不对,全乱了.指定宽度
        @Override
        protected void onFinishInflate() {
            //这个方法是xml解析完毕调用
            super.onFinishInflate();
    
            //获取LinearLayout
            ViewGroup container = (ViewGroup) getChildAt(0);
    
            int childCount = container.getChildCount();
            if (childCount > 2) {
                new IllegalAccessException("不能超过2个子View");
            }
            //获取menu
            mMenuView = container.getChildAt(0);
            //获取内容
            mContentView = container.getChildAt(1);
    
            //指定内容也的宽度
            ViewGroup.LayoutParams contentLayoutParams = mContentView.getLayoutParams();
            //内容的宽度 = 屏幕的宽度
            contentLayoutParams.width = DimenUtils.getScreenWidth(getContext());
            mContentView.setLayoutParams(contentLayoutParams);
    
            //指定menu的宽度
            ViewGroup.LayoutParams menuLayoutParams = mMenuView.getLayoutParams();
            //menu的宽度 = 屏幕的宽度 - mMenuRightMargin
            mMenuWidth = DimenUtils.getScreenWidth(getContext()) - mMenuRightMargin;
            menuLayoutParams.width = mMenuWidth;
            mMenuView.setLayoutParams(menuLayoutParams);
    
            //发现,初始化关闭没有作用
    //        scrollTo(mMenuWidth, 0);
        }
    
        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            super.onLayout(changed, l, t, r, b);
            //初始化关闭menu
            scrollTo(mMenuWidth, 0);
        }
    

    处理触摸事件

        public boolean onTouchEvent(MotionEvent ev) {
            if (ev.getAction() == MotionEvent.ACTION_UP) {
                //只管手指抬起了的事件
                //根据当前滑动的位置处理关闭还是打开
                int currentScrollX = getScrollX();
                if (currentScrollX > mMenuWidth / 2) {
                    //关闭
                    closeMenu();
                } else {
                    //打开
                    openMenu();
                }
                //确保不会调用super,因为super.里面也有滑动的方法
                return true;
            }
            return super.onTouchEvent(ev);
        }
    
        private void closeMenu() {
            scrollTo(mMenuWidth, 0);
            mCurrentMenuState = false;
        }
    
        private void openMenu() {
            scrollTo(0, 0);
            mCurrentMenuState = true;
        }
    

    1.4 处理滑动的缩放

        @Override
        protected void onScrollChanged(int l, int t, int oldl, int oldt) {
            super.onScrollChanged(l, t, oldl, oldt);
            // 打开 Menu l == mMenuWidth --> 0
            // 所以 scale == 0 --> 1.0
            double scale = 1 - l * 1.0 / mMenuWidth;
    
            //右边的contentView 从 1 --> 0.7 缩放
            // 1 --> 0.7
            float rightScale = (float) (1.0 - 0.3 * scale);
            ViewCompat.setScaleX(mContentView, rightScale);
            ViewCompat.setScaleY(mContentView, rightScale);
            //设置锚点
            ViewCompat.setPivotX(mContentView, 0);
            ViewCompat.setPivotY(mContentView, mContentView.getMeasuredHeight() / 2);
        }
    

    1.5 处理快速滑动

        public SlidingMenu(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            //处理快速滑动
            mGestureDetector = new GestureDetector(context, mOnGestureListener);
        }
    
        private GestureDetector.OnGestureListener mOnGestureListener = new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                //Log.e(TAG, "onFling velocityX -->"+velocityX);
                //往右快速滑动为正数,往左快速滑动为负数
    
                if (mCurrentMenuState) {
                    //当menu打开的时候,往左快速滑动关闭menu
                    if (velocityX < 0) {
                        closeMenu();
                        return true;
                    }
                } else {
                    //当menu关闭的时候,往右快速滑动打开menu
                    if (velocityX> 0){
                        openMenu();
                        return true;
                    }
                }
                return super.onFling(e1, e2, velocityX, velocityY);
            }
        };
    
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            //快速滑动处理
            if (mGestureDetector.onTouchEvent(ev)) {
                //当处理了快速滑动就不需要执行下面的逻辑
                return true;
            }
    }
    

    1.6 menu打开的时候点击,内容页关闭menu,并不能响应内容页的Touch事件

    事件拦截

        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            mIntercept = false;
            //menu打开的时候的点击内容,关闭menu,同时不会响应内容页的事件 事件拦截.
            if (mCurrentMenuState){
                //获取点击是位置
                float currentX = ev.getX();
                if (currentX > mMenuWidth){
                    //点击的位置在内容页
                    //关闭menu
                    closeMenu();
    
                    mIntercept = true;
                    //不响应内容的事件
                    return true;
                }
            }
            return super.onInterceptTouchEvent(ev);
        }
    

    完整代码:slidingmenu

    相关文章

      网友评论

          本文标题:自定义View-22.酷狗侧滑菜单效果

          本文链接:https://www.haomeiwen.com/subject/gxiouftx.html