【发布时间】:2013-10-06 13:15:15
【问题描述】:
我正在尝试找出我的自定义视图的优化。我想知道即使视图已经可见,对 View.setVisibility(View.VISIBLE) 的调用是否会强制 Android 框架更新视图可见性(
【问题讨论】:
标签: android optimization view
我正在尝试找出我的自定义视图的优化。我想知道即使视图已经可见,对 View.setVisibility(View.VISIBLE) 的调用是否会强制 Android 框架更新视图可见性(
【问题讨论】:
标签: android optimization view
看看setVisibility():
public void setVisibility(int visibility) {
setFlags(visibility, VISIBILITY_MASK);
if (mBGDrawable != null) mBGDrawable.setVisible(visibility == VISIBLE, false);
}
它只是调用setFlags(),如果没有任何变化,它会立即返回:
....
int changed = mViewFlags ^ old;
if (changed == 0) {
return;
}
即使它(以某种方式)通过了那里,它也会检查各个标志的变化,并且仅在其中一个与原来不同时更新。
【讨论】:
public void setVisibility(int visibility) {
setFlags(visibility, VISIBILITY_MASK);
if (mBackground != null) mBackground.setVisible(visibility == VISIBLE, false);
}
setFlags(...) 方法开头为:
int old = mViewFlags;
mViewFlags = (mViewFlags & ~mask) | (flags & mask);
int changed = mViewFlags ^ old;
if (changed == 0) {
return;
}
所以我很确定这种方法不会做任何事情。否则,除了触发布局和重绘之外,它会做很多事情。
public boolean setVisible(boolean visible, boolean restart) {
boolean changed = mVisible != visible;
if (changed) {
mVisible = visible;
invalidateSelf();
}
return changed;
}
if 将是假的,所以这不会做任何事情。
但是,View#setVisible() 被以下内容覆盖:ImageView、MediaRouteButton、ProgressBar、SurfaceView 和 ViewStub。您需要检查每个实现是否有其他额外功能 - 您可能正在使用这些子类之一。
同样适用于Drawable:有 8 个类覆盖了Drawable#setVisible(boolean, boolean):
根据您的组合,您可能会发现您实际上在做一些额外的事情,因此您需要调查您使用的是哪种View,以及它的背景可绘制对象是什么类型的可绘制对象。
【讨论】:
setVisibility() 通过在里面调用 setFlags 来设置视图标志。如果我们进入 sdk View.setFlags() ,我们可以看到如果标志状态没有改变,这个方法没有任何作用。来自 sdk View.setFlags() 方法的代码:int changed = mViewFlags ^ old;
if (changed == 0) {
return;
}
【讨论】:
我不是 100%,但我不这么认为
来自 View 类的 grepcode,这是来自 setFlags(int flags, int mask) 方法,该方法是从 setVisibility(int visibility) 调用的
int changed = mViewFlags ^ old;
if (changed == 0) {
return;
}
在此之后在同一方法中调用requestLayout()和invalidate()
所以我会说不,它没有
【讨论】: