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

即:将带有图片以及二维码的布局文件生成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. Redis数据倾斜与JD开源hotkey源码分析揭秘

    1 前言 之前旁边的小伙伴问我热点数据相关问题,在给他粗略地讲解一波redis数据倾斜的案例之后,自己也顺道回顾了一些关于热点数据处理的方法论,同时也想起去年所学习JD开源项目hotkey--专门用来 ...

  2. Ant Design Vue中Table的选中详解

    <template> <a-table :columns="columns" :data-source="data" :row-selecti ...

  3. 系统Hosts文件原理和应用

    Hosts的概念 Hosts是一个没有扩展名的系统文件,可以用记事本等工具打开,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联"数据库",当用户在浏览器中输入一个需要 ...

  4. 微信小程序-获取用户位置

    首先我要提供几个文档的链接地址: 首先是官方文档的获取用户位置的API文档地址: 官方文档地址:https://developers.weixin.qq.com/miniprogram/dev/api ...

  5. postman测试Integer[]数组

    背景说明:在做批量删除列表数据的时候,前端发送数组格式给后端,后端使用数组格式(Integer[] ids)接受,需要使用postman测试结果. @ApiOperation("管理系统-删 ...

  6. 应用实践:Paddle分类模型大集成者[PaddleHub、Finetune、prompt]

    相关文章: Paddlenlp之UIE模型实战实体抽取任务[打车数据.快递单] Paddlenlp之UIE分类模型[以情感倾向分析新闻分类为例]含智能标注方案) 项目连接: 应用实践:分类模型大集成者 ...

  7. 【一】飞桨paddle【GPU、CPU】安装以及环境配置+python入门教学

    相关文章: [一]飞桨paddle[GPU.CPU]安装以及环境配置+python入门教学 [二]-Parl基础命令 [三]-Notebook.&pdb.ipdb 调试 [四]-强化学习入门简 ...

  8. 在K8S中,PV和PVC是如何关联?

    在Kubernetes(简称K8s)中,PersistentVolume (PV) 和 PersistentVolumeClaim (PVC) 是实现存储持久化的关键组件.它们之间的关联是用来动态或静 ...

  9. 【Linux】root密码忘记了怎么办【技能篇】一分钟教会你重置root密码

    [Linux]root密码重置 文章目录 前言介绍 操作步骤 尾声 前言介绍 那么这里博主先安利一下一些干货满满的专栏啦! 数据结构专栏:数据结构 这里包含了博主很多的数据结构学习上的总结,每一篇都是 ...

  10. 源代码安装Nginx和PHP

    源代码安装Nginx和PHP 一.安装前准备: 有些工具在安装Nginx必备.譬如gcc用来编译C程序,gcc-c++ 用来编译C++程序,wget用来从网络下载文件. [root@localhost ...