今天遇到一个需求,需要点击分享的时候生成图片以及二维码。

即:将带有图片以及二维码的布局文件生成Bitmap,当然这个布局文件是后台生成的,并不可见,这时候会发现使用Glide加载图片没有反应。

源码分析:

追踪到ViewTarget里面的getSize方法:

void getSize(@NonNull SizeReadyCallback cb) {
int currentWidth = getTargetWidth();
int currentHeight = getTargetHeight();
if (isViewStateAndSizeValid(currentWidth, currentHeight)) {
cb.onSizeReady(currentWidth, currentHeight);
return;
} // We want to notify callbacks in the order they were added and we only expect one or two
// callbacks to be added a time, so a List is a reasonable choice.
if (!cbs.contains(cb)) {
cbs.add(cb);
}
if (layoutListener == null) {
ViewTreeObserver observer = view.getViewTreeObserver();
layoutListener = new SizeDeterminerLayoutListener(this);
observer.addOnPreDrawListener(layoutListener);
}
}

假如获取到的View的宽高不大于0,那么就不会走cb.onSizeReady(currentWidth, currentHeight);也就不会往下执行,而是会给ViewTreeObserver设置一个监听。

我们进去getTargetWidth()方法:

private int getTargetWidth() {
int horizontalPadding = view.getPaddingLeft() + view.getPaddingRight();
LayoutParams layoutParams = view.getLayoutParams();
int layoutParamSize = layoutParams != null ? layoutParams.width : PENDING_SIZE;
return getTargetDimen(view.getWidth(), layoutParamSize, horizontalPadding);
}

然后再到:

private int getTargetDimen(int viewSize, int paramSize, int paddingSize) {
// We consider the View state as valid if the View has non-null layout params and a non-zero
// layout params width and height. This is imperfect. We're making an assumption that View
// parents will obey their child's layout parameters, which isn't always the case.
int adjustedParamSize = paramSize - paddingSize;
if (adjustedParamSize > 0) {
return adjustedParamSize;
}
// Since we always prefer layout parameters with fixed sizes, even if waitForLayout is true,
// we might as well ignore it and just return the layout parameters above if we have them.
// Otherwise we should wait for a layout pass before checking the View's dimensions.
if (waitForLayout && view.isLayoutRequested()) {
return PENDING_SIZE;
}
// We also consider the View state valid if the View has a non-zero width and height. This
// means that the View has gone through at least one layout pass. It does not mean the Views
// width and height are from the current layout pass. For example, if a View is re-used in
// RecyclerView or ListView, this width/height may be from an old position. In some cases
// the dimensions of the View at the old position may be different than the dimensions of the
// View in the new position because the LayoutManager/ViewParent can arbitrarily decide to
// change them. Nevertheless, in most cases this should be a reasonable choice.
int adjustedViewSize = viewSize - paddingSize;
if (adjustedViewSize > 0) {
return adjustedViewSize;
}
// Finally we consider the view valid if the layout parameter size is set to wrap_content.
// It's difficult for Glide to figure out what to do here. Although Target.SIZE_ORIGINAL is a
// coherent choice, it's extremely dangerous because original images may be much too large to
// fit in memory or so large that only a couple can fit in memory, causing OOMs. If users want
// the original image, they can always use .override(Target.SIZE_ORIGINAL). Since wrap_content
// may never resolve to a real size unless we load something, we aim for a square whose length
// is the largest screen size. That way we're loading something and that something has some
// hope of being downsampled to a size that the device can support. We also log a warning that
// tries to explain what Glide is doing and why some alternatives are preferable.
// Since WRAP_CONTENT is sometimes used as a default layout parameter, we always wait for
// layout to complete before using this fallback parameter (ConstraintLayout among others).
if (!view.isLayoutRequested() && paramSize == LayoutParams.WRAP_CONTENT) {
if (Log.isLoggable(TAG, Log.INFO)) {
Log.i(
TAG,
"Glide treats LayoutParams.WRAP_CONTENT as a request for an image the size of this"
+ " device's screen dimensions. If you want to load the original image and are"
+ " ok with the corresponding memory cost and OOMs (depending on the input size),"
+ " use override(Target.SIZE_ORIGINAL). Otherwise, use LayoutParams.MATCH_PARENT,"
+ " set layout_width and layout_height to fixed dimension, or use .override()"
+ " with fixed dimensions.");
}
return getMaxDisplayLength(view.getContext());
}
// If the layout parameters are < padding, the view size is < padding, or the layout
// parameters are set to match_parent or wrap_content and no layout has occurred, we should
// wait for layout and repeat.
return PENDING_SIZE;
}

即:当

layoutParamSize - padding 大于0的时候返回该接结果。

view.getWidth() - padding 大于0的时候返回该结果。

当我们后台加载的布局中ImageView的LayouParam没有设置确切数值的时候,返回的是PENDING_SIZE == 0,这时候像上面所说的,它就不会回调出去,而是会给ViewTreeObserver设置一个监听,addOnPreDrawListener,当测量完毕后开始绘制前会回调该监听。但是由于我们的布局是后台加载的,没有添加到界面上,所以该回调不会走,所以图片也就没法加载。

而我们平常使用的时候,则会回调该监听,重新获取View大小,并回调出去。

所以若要通过Glide加载不可见的图片,那么则需要设置有确切数值大小的LayouParam。

(若分析有误欢迎指正)

转载请标明: https://www.cnblogs.com/tangZH/p/14691697.html

通过Glide加载不可见的图片的更多相关文章

  1. Android使用Glide加载https链接的图片不显示的原因

    平时我们使用Glide加载http网址的图片的时候,图片可以正常加载出来,但是如果服务器端加上了安全认证,当加载自签名的https图片的时候就会报如下错误(证书路径验证异常). 我们如果不修改Glid ...

  2. Android笔记之使用Glide加载网络图片、下载图片

    Glide简介 不想说太多,真的很方便:P)可以节省我不少时间 GitHub地址:https://github.com/bumptech/glide 加载网络图片到ImageView Glide.wi ...

  3. Glide加载图片到自定义的圆形ImageView中不显示

    当使用自定义的圆形ImageView时,发现使用Glide加载并设置默认初始图片时,自定义的ImageView一直显示默认图片,无法更新到加载的图片. 使用下面代码可以解决这个问题 Glide.wit ...

  4. Glide 加载图片

    //通过model获取到图片的url,将Url转换成bitmap对象: //设置不保存内存和硬盘缓存, 1 Glide.with(mContext).load(model.getVideoUrl()) ...

  5. glide 加载圆角图片

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABEIAAAD3CAIAAACW6Gb7AAAgAElEQVR4nOy9e1QbZf74//zO4XvOYz

  6. Android Glide加载图片时转换为圆形、圆角、毛玻璃等图片效果

     Android Glide加载图片时转换为圆形.圆角.毛玻璃等图片效果 附录1简单介绍了Android开源的图片加载框架.在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬 ...

  7. Android中的Glide加载图片

    注意:在Android Studio的项目的build.gradle中添加: compile 'com.github.bumptech.glide:glide:3.6.1' 然后同步一下 目录: 使用 ...

  8. RoundedImageView使用吐槽心得(RoundedImageView与Glide加载图片,第一次加载无法圆角问题)

    最近使用的时候发现一个问题, RoundedImageView与Glide搭配使用的时候,第一次加载图片(内存中没有),后图片无法圆角,后来尝试各种改,最后想到了一个办法,就是让Glide加载图片的 ...

  9. Android Glide 加载图片

    0.借鉴文章地址:http://blog.csdn.net/zivensonice/article/details/51835802 和 http://www.cnblogs.com/zhaoyanj ...

  10. Glide加载图片缓存库出现——You cannot start a load for a destroyed activity

    请记住一句话:不要再非主线程里面使用Glide加载图片,如果真的使用了,请把context参数换成getApplicationContext.

随机推荐

  1. NSSCTF Round#17 Basic CRYPTO

    Level_1 题目 Level_1.py(我把参数整理了一下,看着舒服) #真签到题 from Crypto.Util.number import bytes_to_long, getPrime f ...

  2. 基于知识图谱的《红楼梦》人物关系可视化及问答系统(含码源):命名实体识别、关系识别、LTP简单教学

    基于知识图谱的<红楼梦>人物关系可视化及问答系统(含码源):命名实体识别.关系识别.LTP简单教学 文件树: app.py是整个系统的主入口 templates文件夹是HTML的页面 |- ...

  3. win10下MySQL安装教程(MySql-8.0.26超级详细)

    一.下载安装包: 官网链接:MySQL :: Developer Zone 依次点击步骤如下: 二.MySQL文件配置 解压安装包: 解压后的目录并没有的my.ini文件,没关系可以自行创建在安装根目 ...

  4. Python 字符串与字节数组转换

    整数之间的进制转换: 10进制转16进制: hex(16) ==> 0x10 16进制转10进制: int('0x10', 16) ==> 16 类似的还有oct(), bin() 字符串 ...

  5. DevToys(开发工具) v1.0.2.1

    从事开发工作的朋友们千万不要错过了!今天为大家带来的这款软件可以说是开发人员的必备工具,它就是DevToys软件!DevToys中包含了许多强大实用的开发工具,能够帮助用户将程序开发变得更加简单大大降 ...

  6. CF1916E Happy Life in University 题解

    题目: CF1916E Happy Life in University 链接: 洛谷 或者 CF 前置知识点: 线段树与HH的项链 先简单回顾下HH的项链这题怎么做的吧.先去掉莫队算法,因为这个不是 ...

  7. HarmonyOS 开发入门(三)

    HarmonyOS 开发入门(三) 日常逼逼叨 在开发入门(一)和开发入门(二)中我们描述了 HarmonyOS 开发的语言ArKTs以及Ts简单的入门级语法操作以及开发环境的搭建,接下来我们进入第三 ...

  8. Oracle预防alert日志过大的脚本:del_alertlog.sh

    Oracle预防alert日志过大的脚本 参考:https://blog.csdn.net/jc_benben/article/details/88798523 在原文思路的基础上,做了一些修正,实测 ...

  9. Spring 与 Mybatis 中的 @Repository 与 @Mapper

    @Repository.@Service.@Controller,它们分别对应存储层Bean,业务层Bean,和展示层Bean.如果使用@Repository则需要使用@MapperScan(&quo ...

  10. JS Leetcode 530. 二叉搜索树的最小绝对差 题解分析,再次了解中序遍历

    壹 ❀ 引 本题来自LeetCode 783. 二叉搜索树节点最小距离,题目描述如下: 给你一个二叉搜索树的根节点 root ,返回 树中任意两不同节点值之间的最小差值 . 示例 1: 输入:root ...