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;
}
(どういうわけか)そこを通り過ぎたとしても、個々のフラグの変更をチェックし、そのうちの1つが以前と異なる場合にのみ更新します。
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;
}
したがって、このメソッドは何もしないと確信しています。そうしないと、レイアウトと再描画をトリガーする以外に、多くのことを行うことになります。
Background#setVisibleも同様です:
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)
:
- ClipDrawable
- DrawableContainer
- AnimationDrawable - DrawableContainer から拡張
- InsetDrawable
- LayerDrawable
- RotateDrawble
- ScaleDrawable
- SlideDrawable
組み合わせによっては、実際には余分なことをしていることに気付く場合があるため、View
使用しているのがどのような種類で、その背景の drawable がどの種類の drawable であるかを調査する必要があります。
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()
だから私はノーと言うだろうそれはそうではありません