I'm trying to figure out the optimization for my custom view. I'm wondering if the calling to View.setVisibility(View.VISIBLE) forces the Android framework to update the view visibility (<- forcing the view to redraw) even if the view is already visible.
4 回答
看看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)
:
- ClipDrawable
- 可绘制容器
- AnimationDrawable - 从 DrawableContainer 扩展
- InsetDrawable
- 图层可绘制
- 旋转绘图
- ScaleDrawable
- SlideDrawable
根据您的组合,您可能会发现您实际上正在做一些额外的事情,因此您需要调查View
您正在使用哪种类型以及它的背景可绘制对象是什么类型的可绘制对象。
我不是 100% 但我不这么认为
来自 View 类的 grepcode,这是来自setFlags(int flags, int mask)
调用的方法setVisibility(int visibility)
int changed = mViewFlags ^ old;
if (changed == 0) {
return;
}
在此之后在同一方法中调用requestLayout()
和invalidate()
所以我会说不
setVisibility() 通过在里面调用 setFlags 来设置视图标志。如果我们进入 sdk View.setFlags() ,我们可以看到如果标志状态没有改变,这个方法没有任何作用。来自 sdk View.setFlags() 方法的代码:int changed = mViewFlags ^ old;
if (changed == 0) {
return;
}