美文网首页
SlidingMenu监听滚动事件将主页变暗

SlidingMenu监听滚动事件将主页变暗

作者: wcdd | 来源:发表于2018-07-20 22:54 被阅读0次

    效果演示

    image.png

    首先简单回顾一下slidingmenu的基本用法吧,以代码为主,不过多解释:

    SlidingMenu menu = new SlidingMenu(this);  
            //设置菜单方向  
            menu.setMode(SlidingMenu.LEFT_RIGHT);  
            //设置滑动的范围  
            menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);  
            //设置滑动的宽度  
            menu.setBehindOffset(200);  
            //设置阴影部分的图片  
            menu.setShadowDrawable(R.color.colorPrimaryDark);  
            menu.setShadowWidth(10);  
            //设置淡入淡出的效果  
            menu.setFadeEnabled(true);  
            menu.setFadeDegree(0.4f);  
            //附加到activity  
            menu.attachToActivity(this,SlidingMenu.SLIDING_CONTENT);  
            //设置左右滑动的菜单  
            menu.setMenu(R.layout.slide_method_left);  
    

    这个不是今天的重点,侧拉菜单是初始化出来了,但是如果我要监听菜单的滑出的距离来实时的设置某些view的值,该怎么实现呢?翻阅api及sliding源码,就这有这3个监听,根本不能满足我们的需要:

    [图片上传失败...(image-42f746-1532098401489)]

    没办法只能去翻阅源码咯,源码太多,从哪开始入手呢,擒贼先禽王,谁滑动先找谁!

    /**
         * Set the behind view (menu) content to the given View.
         *
         * @param view The desired content to display.
         */
        public void setMenu(View v) {
            mViewBehind.setContent(v);
        }
    
    //找到初始化的地方
    mViewBehind = new CustomViewBehind(context);
            mViewAbove = new CustomViewAbove(context);
    

    mViewBehind就是我们的菜单view,那mViewAbove是什么呢?其实看名字就已经猜到了,behind代表在下面的菜单,那么above应该是上面的主页面,抱着这个想法我们去证实一下自己的猜测:

    还记得menu.attachToActivity(this,SlidingMenu.SLIDING_CONTENT)这个方法吗?是让activity依附与slidingmenu,他有两种模式:

    case SLIDING_WINDOW:
                mActionbarOverlay = false;
                ViewGroup decor = (ViewGroup) activity.getWindow().getDecorView();
                ViewGroup decorChild = (ViewGroup) decor.getChildAt(0);
                // save ActionBar themes that have transparent assets
                decorChild.setBackgroundResource(background);
                decor.removeView(decorChild);
                decor.addView(this);
                setContent(decorChild);
                break;
            case SLIDING_CONTENT:
                mActionbarOverlay = actionbarOverlay;
                // take the above view out of
                ViewGroup contentParent = (ViewGroup)activity.findViewById(android.R.id.content);
                View content = contentParent.getChildAt(0);
                contentParent.removeView(content);
                contentParent.addView(this);
                setContent(content);
                // save people from having transparent backgrounds
                if (content.getBackground() == null)
                    content.setBackgroundResource(background);
                break;
    
    /**
         * Set the above view content to the given View.
         *
         * @param view The desired content to display.
         */
        public void setContent(View view) {
            mViewAbove.setContent(view);
            showContent();
        }
    

    代码中我们可以明确的看到,不管是那种模式,都是找到当前activity的根布局,然后先把里面的view删掉,然后把this也就是slidingmenu放入根布局中,最后将我们原来的这个主页view设置给了mViewAbove!!是不是也就是证实了我们的猜测,mViewAbove就是我们的主页,我们再找找mViewAbove、mViewBehind的一些相关事件,看能发现些什么。

    一路find,终于有了发现:

    mViewAbove.setOnPageChangeListener(new OnPageChangeListener() {
                public static final int POSITION_OPEN = 0;
                public static final int POSITION_CLOSE = 1;
                public static final int POSITION_SECONDARY_OPEN = 2;
    
                public void onPageScrolled(int position, float positionOffset,
                        int positionOffsetPixels) {
                }
    
                public void onPageSelected(int position) {
                    if (position == POSITION_OPEN && mOpenListener != null) {
                        mOpenListener.onOpen();
                    } else if (position == POSITION_CLOSE && mCloseListener != null) {
                        mCloseListener.onClose();
                    } else if (position == POSITION_SECONDARY_OPEN && mSecondaryOpenListner != null ) {
                        mSecondaryOpenListner.onOpen();
                    }
                }
            });
    

    这个是不是很熟悉,有点想viewpage的滑动事件,就在这里打印log试试效果吧!

    public void onPageScrolled(int position, float positionOffset,
                        int positionOffsetPixels) {
                    Log.i("TAG","positionOffset:"+positionOffset+" , positionOffsetPixels:"+positionOffsetPixels);
                }
    

    打印结果:

    image.png

    对了,就是它了!当主页向左滑动,偏移量数值在慢慢的减少,找到了根源就好办事咯,我给他加一个滚动监听回调,不就能解决我们的问题了吗,这是我自己加的代码:

    private OnScrollDistanceListener mOnScrollDistanceListener;
    
    public void setOnScrollDistanceListener(OnScrollDistanceListener listener){
            this.mOnScrollDistanceListener = listener;
        }
    
        /**
         * 监听SlidingMenu移动距离
         */
        public interface OnScrollDistanceListener{
            void  onPageScrolled( float positionOffset,
                                            int positionOffsetPixels);
        }
    
    public void onPageScrolled(int position, float positionOffset,
                        int positionOffsetPixels) {
                    if(mOnScrollDistanceListener != null){
                        mOnScrollDistanceListener.onPageScrolled(Math.abs(positionOffset),Math.abs(positionOffsetPixels));
                    }
                }
    

    有了移动的距离,是不是该给主页view设置半透明黑色遮障了,大家一定第一个想到的就是getWindow().getAttributes();然后设置alpha,这样搞了你会发现,什么鬼!我明明只想将滑出时的主页变成灰色,为什么我的菜单也变灰了。要知道getWindow()指的是整个activity界面,在刚刚的源码中我们已经看到slidingmenu已经将菜单和主页都放在了activity中,那么当然是全部都变灰了!!!

    有人在想了,那我们来设置主页的alpha行吗?行,这会变色的范围定位准了,但是alpha是从不透明到透明的一个过度,不透明的时候界面变成了白色,而不是我们需要的灰色,这怎么搞?其实很简单,用最原始的办法,给主页布局最上层加一个view,大小与整个主页相等,然后通过设置它的背景色和透明度来实现,虽然听上去low一点,但是暂时真的没有找到更好的方法来实现:

    <!--遮障view-->
    <View
            android:id="@+id/v_filter"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#494949"
            android:visibility="gone"
            />
    
     //滑动距离监听
            slidingMenu.setOnScrollDistanceListener(new SlidingMenu.OnScrollDistanceListener() {
                @Override
                public void onPageScrolled(float positionOffset, int positionOffsetPixels) {
                    setActivityFilter(positionOffset);
                }
            });
    
        /**
         * 设置activity滤镜效果
         */
        private void setActivityFilter(float positionOffset) {
            float alpha = positionOffset * 0.7f;
            iv_filter.setAlpha(alpha);
            if (alpha <= 0) {
                if (iv_filter.isShown())
                    iv_filter.setVisibility(View.GONE);
            } else {
                if (!iv_filter.isShown())
                    iv_filter.setVisibility(View.VISIBLE);
            }
        }
    

    相关文章

      网友评论

          本文标题:SlidingMenu监听滚动事件将主页变暗

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