- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有一个 GridView
用于显示一些图标。
在我阅读本文之前 Displaying Bitmaps Efficiently从 Android 开发者网站,我直接在适配器的 getView()
中从本地路径解码位图,如下所示:
public View getView(int position, View convertView, ViewGroup parent) {
...
ImageView icon = ...... (from getTag() of convertView)
icon.setImageBitmap(BitmapUtil.decode(iconPath));
...
}
这种方式无论如何都很好,我称之为[直接模式],getView()
方法的输出日志应该是:
getView(0) // measure kid's layout.
getView(0)
getView(1)
getView(2)
...
getView(n) // when scrolling gridview.
getView(n+1)
...
getView(n+3) // scrolling again.
getView(n+4)
...
然后我尝试将代码更改为文章 Displaying Bitmaps Efficiently 中提到的 [Loader Mode] ,如下:
public View getView(int position, View convertView, ViewGroup parent) {
...
ImageView icon = ...... (from getTag() of convertView)
loadIcon(icon, iconPath);
...
}
在 loadIcon()
中:
...
final CacheImageLoader loader = new CacheImageLoader(getActivity(), imageView, imageUrl, savePath);
final AsyncDrawable asyncDrawable = new AsyncDrawable(getResources(), placeHolderBitmap, loader);
imageView.setImageDrawable(asyncDrawable);
在 Loader 的监听器中:
@Override
public void onLoadComplete(Loader<Bitmap> arg0, Bitmap arg1) {
...
ImageView imageView = imageViewReference.get();
if (result != null && imageView != null) {
imageView.setImageBitmap(result);
}
}
基本上和训练代码一样,其实这种方式也可以。但是,我发现了一些不同的东西,在这种模式下,适配器中的 getView()
方法被调用了太多次,但是,这些对该方法的重复调用总是使用“位置”参数 == 0,这意味着有些东西反复调用 getView(0, X, X)
。
getView(0) // measure kid's layout.
getView(0)
getView(1)
getView(2)
...
getView(0) // loader completed then imageView.setImageBitmap(result);
getView(0) // same as above
getView(0)
getView(0)
...
getView(n) // when scrolling gridview.
getView(n+1)
getView(n+2)
getView(0) // loader completed then imageView.setImageBitmap(result);
getView(0) // same as above
getView(0)
...
getView(n+3) // scrolling again.
getView(n+4)
getView(0) // loader completed then imageView.setImageBitmap(result);
getView(0) // same as above
getView(0)
这不好,因为我在 getView()
中使用了加载程序。我检查了源代码,发现它们最初是由 imageView.setImageBitmap(result)
在加载器的 onLoadComplete
方法和 中调用的 ImageView
:
/**
* Sets a drawable as the content of this ImageView.
*
* @param drawable The drawable to set
*/
public void setImageDrawable(Drawable drawable) {
...
int oldWidth = mDrawableWidth;
int oldHeight = mDrawableHeight;
updateDrawable(drawable);
if (oldWidth != mDrawableWidth || oldHeight != mDrawableHeight) {
requestLayout();
}
invalidate();
}
}
这里,requestLayout()
是 View 的方法,总是在 View.class 中的 [Direct Mode] 或 [Loader Mode] 中执行:
public void requestLayout() {
mPrivateFlags |= FORCE_LAYOUT;
mPrivateFlags |= INVALIDATED;
if (mLayoutParams != null) {
mLayoutParams.onResolveLayoutDirection(getResolvedLayoutDirection());
}
if (mParent != null && !mParent.isLayoutRequested()) {
mParent.requestLayout();
}
}
但是不同的是:在[直接模式]中,mParent.requestLayout()
被调用一次,但在[加载器模式]中,每次我调用imageView .setImageBitmap(result);
,mParent.requestLayout()
也会被调用,表示mParent.isLayoutRequested()
返回false
和 mParent.requestLayout();
将导致 GridView
通过调用 obtainView()
来测量其 child 的布局第一个 child ,然后导致 getView(0, X, X)
:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
...
mItemCount = mAdapter == null ? 0 : mAdapter.getCount();
final int count = mItemCount;
if (count > 0) {
final View child = obtainView(0, mIsScrap);
...
所以,我的问题是:如果我使用[加载器模式],为什么 mParent.isLayoutRequested()
返回 false
?还是只是正常情况?
最佳答案
isLayoutRequested
只是为了告诉您此 View
的布局是否已挂起.也就是说,在 requestLayout
之后被称为,isLayoutRequested
将返回 true 直到下一个布局传递完成。 checkin requestLayout
的唯一原因是为了避免重复调用requestLayout
如果无论如何都要进行布局,则在父级上。 isLayoutRequested
这里是一个红鲱鱼:这不是 onMeasure
的原因被反复调用。
根本问题是ImageView
每当您更改其可绘制对象时都会请求新布局。这是必要的,原因有两个:-
adjustViewBounds
已设置。这可能反过来影响其他 View 的大小,具体取决于布局:ImageView
本身没有足够的信息知道。ImageView.onMeasure
负责计算需要调整多少可绘制对象以适应 ImageView
的边界,根据比例模式。如果新的drawable与旧drawable的大小不同,ImageView
必须再次测量以重新计算所需的缩放比例。您只能通过保留 Bitmap
的本地缓存来解决加载程序过多的问题。 s 由装载机返回。缓存可能包含所有 Bitmap
s 如果您知道没有那么多,或者只是 n 最近使用的。在您的 getView
,首先检查 Bitmap
如果该项目存在于缓存中,则返回 ImageView
已经设置为 Bitmap
.只有不在缓存中时才需要使用加载器。
注意:如果底层数据可以更改,您现在需要确保在调用 invalidate
的同时使缓存无效在 GridView
或通过 ContentResolver
通知.我在我的应用程序中使用了一些自制代码来实现这一点,它对我来说效果很好,但是 Square 的好人有一个名为 Picasso 的开源库如果您愿意,可以为您完成所有艰苦的工作。
关于android - 在 gridview 适配器中,getView(position == 0) 在加载器中的 setImageBitmap() 被调用太多次以测量布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12561295/
我想要显示正在加载的 .gif,直到所有内容都已加载,包括嵌入的 iframe。但是,目前加载 gif 会在除 iframe 之外的所有内容都已加载后消失。我怎样才能让它等到 iframe 也加载完毕
首先,这是我第一次接触 Angular。 我想要实现的是,我有一个通知列表,我必须以某种方式限制 limitTo,因此元素被限制为三个,在我单击按钮后,其余的应该加载。 我不明白该怎么做: 设置“ V
我正在尝试在我的设备上运行这个非常简单的应用程序(使用 map API V2),并且出于某种原因尝试使用 MapView 时: 使用 java 文件: public class MainMap e
我正在使用 Python 2.6、Excel 2007 Professional 和最新版本的 PyXLL。在 PyXLL 中加载具有 import scipy 抛出异常,模块未加载。有没有人能够在
我想做这个: 创建并打包原始游戏。然后我想根据原始游戏中的蓝图创建具有新网格/声音/动画和蓝图的其他 PAK 文件。原始游戏不应该知道有关其他网格/动画/等的任何信息。因此,我需要在原始游戏中使用 A
**摘要:**在java项目中经常会使用到配置文件,这里就介绍几种加载配置文件的方法。 本文分享自华为云社区《【Java】读取/加载 properties配置文件的几种方法》,作者:Copy工程师。
在 Groovy 脚本中是否可以执行条件导入语句? if (test){ import this.package.class } else { import that.package.
我正在使用 NVidia 视觉分析器(来自 CUDA 5.0 beta 版本的基于 eclipse 的版本)和 Fermi 板,我不了解其中两个性能指标: 全局加载/存储效率表示实际内存事务数与请求事
有没有办法在通过 routeProvider 加载特定 View 时清除 Angular JS 存储的历史记录? ? 我正在使用 Angular 创建一个公共(public)安装,并且历史会积累很多,
使用 Xcode 4.2,在我的应用程序中, View 加载由 segue 事件触发。 在 View Controller 中首先调用什么方法? -(void) viewWillAppear:(BOO
我在某些Django模型中使用JSONField,并希望将此数据从Oracle迁移到Postgres。 到目前为止,当使用Django的dumpdata和loaddata命令时,我仍然没有运气来保持J
创建 Nib 时,我需要创建两种类型:WindowNib 或 ViewNib。我看到的区别是,窗口 Nib 有一个窗口和一个 View 。 如何将 View Nib 加载到另一个窗口中?我是否必须创建
我想将多个env.variables转换为静态结构。 我可以手动进行: Env { is_development: env::var("IS_DEVELOPMENT")
正如我从一个测试用例中看到的:https://godbolt.org/z/K477q1 生成的程序集加载/存储原子松弛与普通变量相同:ldr 和 str 那么,宽松的原子变量和普通变量之间有什么区别吗
我有一个重定向到外部网站的按钮/链接,但是外部网站需要一些时间来加载。所以我想添加一个加载屏幕,以便外部页面在显示之前完全加载。我无法控制外部网站,并且外部网站具有同源策略,因此我无法在 iFrame
我正在尝试为我的应用程序开发一个Dockerfile,该文件在初始化后加载大量环境变量。不知何故,当我稍后执行以下命令时,这些变量是不可用的: docker exec -it container_na
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我刚刚遇到一个问题,我有一个带有一些不同选项的选择标签。 现在我想检查用户选择了哪些选项。 然后我想将一个新的 html 文件加载到该网站(取决于用户选中的选项)宽度 javascript,我该怎么做
我知道两种保存/加载应用程序设置的方法: 使用PersistentStore 使用文件系统(存储,因为 SDCard 是可选的) 我想知道您使用应用程序设置的做法是什么? 使用 PersistentS
我开始使用 Vulkan 时偶然发现了我的第一个问题。尝试创建调试报告回调时(验证层和调试扩展在我的英特尔 hd vulkan 驱动程序上可用,至少它是这么说的),它没有告诉我 vkCreateDeb
我是一名优秀的程序员,十分优秀!