美文网首页
模仿华为杂志锁屏上滑模糊效果实现

模仿华为杂志锁屏上滑模糊效果实现

作者: a_simple_coder | 来源:发表于2017-10-31 17:27 被阅读0次

    由于项目需要,实现一个类似于华为杂志锁屏上滑模糊的效果,先说一下思路:

    1. 自定义一个类似抽屉拖拽效果从手机底部滑进的view,支持手势滑动,并提供上下滑动变化监听;
    2. 在上下滑动变化的监听方法,截屏:截取自定义view下面的视图,进行模糊处理,然后作为view的背景。

    下面说一下详细细节:
    首先,从底部滑出的view在网上有很多,我这里用的是https://github.com/yingLanNull/ScrollLayout,我是直接下载源码,这样可以根据自己的需求进行修改:源码中,view的状态有三个:CLOSE、OPEN、EXIT,其中:

    • CLOSE是view滑到屏幕顶部时的状态;
    • OPEN是view显示时的状态;
    • EXIT时view隐藏或滑到屏幕底部时的状态;
      这里的view是继承的ScrollLayout:
    int offset = (int) (ScreenUtil.getScreenHeight((Activity)context) * 0.5);
    setMinOffset(0); //view滑到屏幕顶部时view下方视图的可见距离
    setMaxOffset(offset); //打开状态时内容显示区域的高度
    setExitOffset(0); //view退出时屏幕底部可见距离,0为不可见
    setIsSupportExit(true); //是否支持下滑退出,支持会有下滑到最底部时的回调
    setAllowHorizontalScroll(true);
    setOnScrollChangedListener(mOnScrollChangedListener); //设置上下滑动监听
    setToExit(); //默认令view置于屏幕底部
    

    在上下滚动的监听中截取自定义view下面的视图,进行模糊处理,然后作为view的背景:

        private ScrollLayout.OnScrollChangedListener mOnScrollChangedListener = new ScrollLayout.OnScrollChangedListener(){
            @Override
            public void onScrollProgressChanged(float currentProgress) {
                NLog.i(TAG + ":onScrollProgressChanged currentProgress:"+currentProgress);
                if (currentProgress > -1) {
                    float precent = 255;
                    if(currentProgress>= 0) {
                        precent = 255 * currentProgress;
                        if (precent > 255) {
                            precent = 255;
                        } else if (precent < 0) {
                            precent = 0;
                        }
                    }
                    BlurBitmapUtil.blur(rootView, toBlurView, 14, 8); //截取自定义toBlurView下面的视图,进行模糊处理,然后作为toBlurView的背景
                    if(getBackground()!= null) {
                        getBackground().setAlpha(255 - (int) precent);
                    }
                }
            }
    
            @Override
            public void onScrollFinished(ScrollLayout.Status currentStatus) {
                if (currentStatus.equals(ScrollLayout.Status.EXIT)) {
                }
            }
    
            @Override
            public void onChildScroll(int top) {
            }
        };
    

    blur的方法如下:

     /**
         * 设置高斯模糊
         *
         * @param fromView    从某个View获取截图
         * @param toView      高斯模糊设置到某个View上
         * @param radius      模糊度
         *                    取值在 0 - 25 之间,值越大,越模糊。
         * @param scaleFactor 缩放比例  一般设置为 8 即可,不需要特别注意。
         *                    设置这个属性,先进性缩放,再进行高斯模糊,效果会更好一点。
         */
        @SuppressWarnings("deprecation")
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
        public static void blur(View fromView, View toView, float radius,
                                float scaleFactor) {
    
            // 获取View的截图
    //        fromView.buildDrawingCache();
    //        Bitmap bkg = fromView.getDrawingCache();
    
            NLog.i(TAG + ":blur: bkg:"+bkg);
            //无需每次都截取,节约时间
            if(bkg == null){
                bkg = BitmapUtil.takeShotBy(fromView);
            }
    
            if (radius < 1 || radius > 26) {
                scaleFactor = 8;
                radius = 2;
            }
    
            Bitmap overlay = Bitmap.createBitmap(
                    (int) (toView.getWidth() / scaleFactor),
                    (int) (toView.getHeight() / scaleFactor),
                    Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(overlay);
    
    
            int[] position = new int[2];
            toView.getLocationInWindow(position);
            int x = position[0];
            int y = position[1];
    
            NLog.i(TAG + ":blur: x:"+x+";y:"+y+";toView.getTop():"+toView.getTop());
            canvas.translate(-x / scaleFactor, -y
                    / scaleFactor);
            canvas.scale(1 / scaleFactor, 1 / scaleFactor);
            Paint paint = new Paint();
            paint.setFlags(Paint.FILTER_BITMAP_FLAG);
            canvas.drawBitmap(bkg, 0, 0, paint);
    
            overlay = doBlur(overlay, (int) radius, true);//这个方法用的是FastBlur,自己百度就有
            toView.setBackground(new BitmapDrawable(overlay));
        }
    

    基本就可以了,代码已上传至GitHub:https://github.com/ruoki/ScrollLayoutWithBlur.git,欢迎修正和star!

    相关文章

      网友评论

          本文标题:模仿华为杂志锁屏上滑模糊效果实现

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