• 关于安卓毛玻璃实现(二)动态毛玻璃recyclerview


    上文说到,一个单独的页面实现毛玻璃

    博客地址

    但是目前,这种方案放在了recyclerview中,就会有性能问题了,为什么?recyclerview因为其加载数据的缓存性质,会同时加载多个view,如果所有view都在做动态毛玻璃,那性能开销可想而知。

    !!!代码地址在文末!!!

    环境:

    1、win10 androidstudio4.4.0

    2、jdk 1.8

    场景:

    recyclerview使用了linearlayoutmanager,pagersnaphelper分页滑动。

    思路:

    如果减少性能开销?有一下方法:

    (一)用户滑动recyclerview的时候,暂停动态毛玻璃

    (二)毛玻璃控件失去焦点的时候,暂停毛玻璃

    (三)非当前页显示时,暂停毛玻璃

    实现:

    (一)通过定义一些对象,分别记录当前用户的滑动位置,滑动状态(滑动中,停止滑动)等。再结合毛玻璃在recyclerview中的位置,进行比对实现。核心代码如下:

                if(getmAdapterPos() == LibPicBlurDragConstant.getInstance().getDragPos()){
                    if(LibPicBlurDragConstant.getInstance().isDrag()){
                        return false;
                    }
                }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    上面代码的意思就是,如果拖动位置和当前毛玻璃控件位置相等且拖动中,就暂停毛玻璃行为。

    (二)失去监听的判断,通过以下代码即可捕获:

        @Override
        public void onWindowFocusChanged(boolean hasWindowFocus) {
            super.onWindowFocusChanged(hasWindowFocus);
            Log.d(TAG, "onWindowFocusChanged hasWindowFocus: " + hasWindowFocus + " mIdentify: " + mIdentify);
            if (hasWindowFocus) {
                setCanBlur(true);
            } else {
                setCanBlur(false);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    (三)由于毛玻璃的位置,是通过windowlocation方法获取的,所以,只要得出离屏位置,即可得出是否在当前页面。注意!!!
    调用该库中,需要自定义一个父类布局(recyclerview场景),替换为原来的Window DecoreView,因为这里涉及的是一个动态绘制显示的问题,所以要替换。核心代码如下:
    离屏位置判断:

                final int[] locations = new int[2];
    //            parentView.getLocationOnScreen(locations);
    //            Log.d(TAG, "checkScreenLocation " + mIdentify + " parentSc: " + locations[1] + " parentHe: " + parentView.getMeasuredHeight());
                getLocationOnScreen(locations);
                int childScreenHeight = locations[1];
    //            Log.d(TAG, "checkScreenLocation " + mIdentify + " childSc: " + locations[1] + " childHe: " + getMeasuredHeight());
    
                //离屏位置----------------------------------------------------------
                if (childScreenHeight <= 0) {
                    //上一页
                    return false;
                }
                if (childScreenHeight >= parentView.getMeasuredHeight()) {
                    return false;
                }
                //离屏位置----------------------------------------------------------
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    自定义decoreview设置:

        protected View getActivityDecorView() {
            if(mCusDecorView!=null){
                return mCusDecorView;
            }
            Context ctx = getContext();
            for (int i = 0; i < 4 && !(ctx instanceof Activity) && ctx instanceof ContextWrapper; i++) {
                ctx = ((ContextWrapper) ctx).getBaseContext();
            }
            if (ctx instanceof Activity) {
                return ((Activity) ctx).getWindow().getDecorView();
            } else {
                return null;
            }
        }
    
        public void setmCusDecorView(View mCusDecorView) {
            this.mCusDecorView = mCusDecorView;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    至此,全部代码已经列出。

    代码地址

  • 相关阅读:
    OpenCV数字图像处理基于C++:灰度变换
    初识docker插件
    taro3.*中使用 dva 入门级别的哦
    程序员都看不懂的代码
    OVN数据库备份和恢复
    组件-ulog
    记录:R语言生成热图(非相关性)
    元数据管理Apache Atlas编译集成部署及测试
    SpringBoot 项目实战 ~ 5.菜品管理
    从React源码分析看useEffect
  • 原文地址:https://blog.csdn.net/motosheep/article/details/127849463