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

即:将带有图片以及二维码的布局文件生成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. Flask闪现

    目录 九.闪现 9.1 什么是闪现? 九.闪现 9.1 什么是闪现? -设置:flash('aaa') -取值:get_flashed_message() - -假设在a页面操作出错,跳转到b页面,在 ...

  2. [置顶] python常用web开发框架

    Flask篇 第一篇:初识Flask.快速启动 第二篇:Flask四剑客 第三篇:Flask的配置文件 第四篇:Flask路由 第五篇:Flask模板渲染 第六篇:Flask的请求与响应 第七篇:Fl ...

  3. Liunx网络配置

    1.安装精简版:CentOS-7-x86_64-Minimal-2009.iso 2.进入配置文件:  vi /etc/sysconfig/network-scripts/ifcfg-ens33 3. ...

  4. 来啦!2020 Java开源项目权威排名解读:Spring Boot排名稳定、Shiro未上榜

    这篇文章对于我们做技术选型以及技术学习都有极强的指导性作用,建议收藏! 原创不易,若有帮助,欢迎点赞! 推荐: 接近100K star 的Java学习/面试指南 Github 95k+点赞的Java面 ...

  5. C++ Boost 函数与回调应用

    #include <iostream> #include <string> #include <boost\bind.hpp> using namespace st ...

  6. Linux 系统Apache配置SSL证书

    在Centos7系列系统下,配置Apache服务器,给服务器增加SSL证书功能,让页面访问是不再提示不安全,具体操作流程如下. 1.第一步首先需要安装mod_ssl模块,执行yum install - ...

  7. Asp .Net Core 系列:Asp .Net Core 配置 System.Text.Json

    目录 简介 Asp .Net Core 如何配置 System.Text.Json 所有配置 全局配置 对比 Newtonsoft.Json 无实体类型下操作 Json 自定义转换器 处理 Dynam ...

  8. PBKDF2算法:保护密码安全的重要工具

    摘要:在当今的数字世界中,密码安全是至关重要的.为了保护用户密码免受未经授权的访问和破解,Password-Based Key Derivation Function 2 (PBKDF2)算法成为了一 ...

  9. grafana+prometheus+loki的使用

    grafana官网:https://grafana.com/zh-cn/grafana/ grafana下载:https://grafana.com/grafana/download?pg=graf& ...

  10. CSS文本,字体设置与元素边框,阴影,显示模式

    什么是元素的显示模式 网页中的标签很多,在不同的地方使用不同类型的标签. 元素显示模式就是标签以什么方式进行显示.如:div自己占一行,span一行可以放多个. HTML元素一般分为块元素和行内元素两 ...