我正在尝试找出自定义视图的优化。我想知道调用View.setVisibility(View.VISIBLE)是否强制Android框架更新视图可见性(< - 强制视图重绘),即使视图已经可见。
答案 0 :(得分:5)
看看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;
}
即使它(以某种方式)过去了,它也会检查各个标志是否发生变化,只有当其中一个标志与其不同时才会更新。
答案 1 :(得分:3)
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
将为false,因此不会执行任何操作。
但是,View#setVisible()
会被ImageView
,MediaRouteButton
,ProgressBar
,SurfaceView
和ViewStub
覆盖。如果它还有其他任何额外的东西,您需要检查每个实现 - 您可能正在使用其中一个子类。
同样适用于Drawable
:有8个类覆盖Drawable#setVisible(boolean, boolean)
:
根据您的组合,您可能会发现您实际上正在做一些额外的事情,因此您需要调查您正在使用的View
类型及其背景可绘制的内容。
答案 2 :(得分:1)
setVisibility()通过调用setFlags里面设置视图标志..如果我们进入sdk View.setFlags(),我们可以看到如果标志状态没有改变,这个方法无关。来自sdk的代码View.setFlags()方法:int changed = mViewFlags ^ old;
if (changed == 0) {
return;
}
答案 3 :(得分:1)
我不是100%,但我不相信
来自View类的grepcode,这是来自setFlags(int flags, int mask)
setVisibility(int visibility)
方法
int changed = mViewFlags ^ old;
if (changed == 0) {
return;
}
之后在同一方法中调用requestLayout()
和invalidate()
所以,我会说不,它不会