美文网首页Android开发
NineGridImageView的onLayout死循环

NineGridImageView的onLayout死循环

作者: 已迁至知乎_此不再维护 | 来源:发表于2019-03-02 17:42 被阅读0次

    NineGridImageView是之前使用过的一个控件,但其单行最多支持3张图片的限制使其不能满足产品的效果图,因此决定对其仿制。

    NineGridImageView控件提供了NineGridImageViewAdapter使调用者定制自己的图片加载框架(ImageLoaderGlidePicasso等)、图片显示控件(ImageViewCircleImageViewPinchImageView)以及图片点击事件(业务逻辑)。

    在仿制的过程中,由于只是为了实现项目功能,将NineGridImageViewAdapter直接省掉了,图片加载框架内置Glide实现,图片显示控件内置ClickFeedbackImageView实现,点击监听则通过接口回调实现个性化。

    但在使用的过程中会发现图片加载不出来(部分会加载出来,部分加载失败)。仔细对照源码确定无误,于是就采用打印日志的方式定位错误。在layoutChildrenView()方法中的日志无限循环。将内置的图片加载框架切换为ImageLoader发现日志打印了多次(但不是无限循环),且图片能够正常加载。

    看来是Glide的问题了。(即Glide是死循环,图片部分加载成功;ImageLoader是有限多次循环,图片全部加载成功)。

    于是google【Glide onLayout】发现了这篇文章这篇文章

    重点有【addView执行一次会导致一次requestLayout和invalidate...官方用的是addViewInLayout或者attachViewToParent取代addView...】。然后赶紧将代码中的addView替换为了addViewInLayout方法,发现依然不行:该循环的还循环,该失败的还失败。

    最终将源码中的

        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            layoutChildrenView();
        }
    

    修改为

        @Override
        protected void onLayout(boolean changed, int l, int t, int r, int b) {
            if (changed) {
                layoutChildrenView();
            }
        }
    

    发现循环的问题解决,但Glide图片全部加载失败,ImageLoader加载图片成功。

    总结

    1. addView方法:建议在Activity中对目标ViewGroup调用;而在自定义View的时候则需在addViewInLayout后调用requestLayout以提高性能;
    2. Glide图片加载成功之后会导致change为false的onLayout的方法调用,但ImageLoader则不会。

    相关文章

      网友评论

        本文标题:NineGridImageView的onLayout死循环

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